Explores how to write a tic-tac-toe API that meets some interesting static typing constraints. Specifically, programs using the API may fail to compile, depending on the state of play in the game, such as trying to call move() with an already completed game board. The real theme of the presentation is not so much solving the tic-tac-toe problem but, rather, pushing static typing to its limits (and some might argue beyond its useful limits—you will have to judge for yourself).
The latest emerging tools and frameworks allow us to write applications (and test them!) much more productively than ever before. This talk explores that concept through a whirlwind tour of numerous advanced testing techniques. A significant emphasis will be on the use of testing DSLs and the use of advanced scripting aproaches using the Groovy programming language (though the principals apply equally well with numerous recent innovative languages).
Video: https://www.youtube.com/watch?v=SfrEThI_m7g
Source code: https://github.com/Alotor/2015-greach-groovy-dsls
Behind each good Groovy library or framework there is a good DSL (Domain Specific Language). And this is not by chance, one of the most exciting features of Groovy is its amazing syntax flexibility and metaprogramming capabilities that allow us do things in a highly expressive manner through DSLs.
In this talk I’ll explain the basics of doing DLS’s with Groovy. What you’ll need to start and what to investigate deeper. Also, we’ll check some of the most well known ones libraries like Spock, Gradle or Grails so you can use their techniques in your own Groovy projects.
The latest emerging tools and frameworks allow us to write applications (and test them!) much more productively than ever before. This talk explores that concept through a whirlwind tour of numerous advanced testing techniques. A significant emphasis will be on the use of testing DSLs and the use of advanced scripting aproaches using the Groovy programming language (though the principals apply equally well with numerous recent innovative languages).
Video: https://www.youtube.com/watch?v=SfrEThI_m7g
Source code: https://github.com/Alotor/2015-greach-groovy-dsls
Behind each good Groovy library or framework there is a good DSL (Domain Specific Language). And this is not by chance, one of the most exciting features of Groovy is its amazing syntax flexibility and metaprogramming capabilities that allow us do things in a highly expressive manner through DSLs.
In this talk I’ll explain the basics of doing DLS’s with Groovy. What you’ll need to start and what to investigate deeper. Also, we’ll check some of the most well known ones libraries like Spock, Gradle or Grails so you can use their techniques in your own Groovy projects.
Ruby plays to many programming paradigms. It's an object-oriented language that can be used in a functional or an imperative/procedural way. But Ruby does not often get used as a logic programming language. In this talk I'll explore logic programming using Ruby. What is it, and is it a tool you want to add to your toolbox? We'll touch on several libraries, we'll primary look at an implementation of minikanren (http://minikanren.org/) for Ruby.
Expression trees is an obscure, although very interesting feature in .NET. Most people probably think of it as something synonymous with object-relational mapping frameworks, but despite being its most common use case, it’s not the only one. There are a lot of creative things you can do with expression trees, including code generation, transpilation, metaprogramming, and more. During this talk, I will explain what this feature really is about and guide you through some examples where it provides real-life benefits.
We'll talk about:
What is an expression tree
How to compile code at runtime
How to make reflection faster
How to implement generic operators
How to turn DSLs into expression trees
How to make metaprogramming type-safe
How to translate a lambda into a different language...and more
Slides from Advaned Python lectures I gave recently in Haifa Linux club
Advanced python, Part 1:
- Decorators
- Descriptors
- Metaclasses
- Multiple inheritance
Grooscript is an open source project, a little framework that convert groovy code to javascript, more info in grooscript.org.
Javascript is cool now, a vibrant community with many new developments. Web development is moving to client size and you must be start to worry about javascript and all the new awesome tools for it. With grooscript, you can join this new wave with our lovely groovy. You can code all the logic of your application in groovy, test with spock, use gradle or any other java or groovy framework. Grooscript will convert your application code to javascript and then you can use it in the browser or Node.js.
In this talk I will introduce about grooscript, how started, how can be used, explore its limitations,… Also I will show grooscript grails plugin, and what do you can do with it. We will take a look at Node.js plugin and gradle plugin, and how to use this tools. I will show some demos of different ways to use grooscript.
Neo4j comes with enhanced connectivity of data and whiteboard friendly paradigm. It also brings a gremlin in your code : one of the supported graph query language brings a refreshing look at how one can search for data in a vast and interconnect web of data. Gremlin provides an abstract layer that make it easy to express your business logic without fighting with the code. It may even change your mind on object oriented programming.
Design Patterns - Compiler Case Study - Hands-on ExamplesGanesh Samarthyam
This presentation takes a case-study based approach to design patterns. A purposefully simplified example of expression trees is used to explain how different design patterns can be used in practice. Examples are in C#, but is relevant for anyone who is from object oriented background.
Ruby plays to many programming paradigms. It's an object-oriented language that can be used in a functional or an imperative/procedural way. But Ruby does not often get used as a logic programming language. In this talk I'll explore logic programming using Ruby. What is it, and is it a tool you want to add to your toolbox? We'll touch on several libraries, we'll primary look at an implementation of minikanren (http://minikanren.org/) for Ruby.
Expression trees is an obscure, although very interesting feature in .NET. Most people probably think of it as something synonymous with object-relational mapping frameworks, but despite being its most common use case, it’s not the only one. There are a lot of creative things you can do with expression trees, including code generation, transpilation, metaprogramming, and more. During this talk, I will explain what this feature really is about and guide you through some examples where it provides real-life benefits.
We'll talk about:
What is an expression tree
How to compile code at runtime
How to make reflection faster
How to implement generic operators
How to turn DSLs into expression trees
How to make metaprogramming type-safe
How to translate a lambda into a different language...and more
Slides from Advaned Python lectures I gave recently in Haifa Linux club
Advanced python, Part 1:
- Decorators
- Descriptors
- Metaclasses
- Multiple inheritance
Grooscript is an open source project, a little framework that convert groovy code to javascript, more info in grooscript.org.
Javascript is cool now, a vibrant community with many new developments. Web development is moving to client size and you must be start to worry about javascript and all the new awesome tools for it. With grooscript, you can join this new wave with our lovely groovy. You can code all the logic of your application in groovy, test with spock, use gradle or any other java or groovy framework. Grooscript will convert your application code to javascript and then you can use it in the browser or Node.js.
In this talk I will introduce about grooscript, how started, how can be used, explore its limitations,… Also I will show grooscript grails plugin, and what do you can do with it. We will take a look at Node.js plugin and gradle plugin, and how to use this tools. I will show some demos of different ways to use grooscript.
Neo4j comes with enhanced connectivity of data and whiteboard friendly paradigm. It also brings a gremlin in your code : one of the supported graph query language brings a refreshing look at how one can search for data in a vast and interconnect web of data. Gremlin provides an abstract layer that make it easy to express your business logic without fighting with the code. It may even change your mind on object oriented programming.
Design Patterns - Compiler Case Study - Hands-on ExamplesGanesh Samarthyam
This presentation takes a case-study based approach to design patterns. A purposefully simplified example of expression trees is used to explain how different design patterns can be used in practice. Examples are in C#, but is relevant for anyone who is from object oriented background.
Clojure is a new dialect of LISP that runs on the Java Virtual Machine (JVM). As a functional language, it offers great benefits in terms of programmer productivity; as a language that runs on the JVM, it also offers the opportunity to reuse existing Java libraries. Simon’s interest is in using Clojure to build desktop applications with the Java Swing GUI library. In this presentation Simon discusses how the power of Clojure can be applied to Swing, and whether it hits the sweet spot.
Go 1.10 Release Party, featuring what's new in Go 1.10 and a few deep dives into how Go works.
Presented at the PDX Go Meetup on April 24th, 2018.
https://www.meetup.com/PDX-Go/events/248938586/
What features of modern programming languages allow you to maximise creativity and express solutions to problems elegantly and efficiently. This is a summary of features of the latest languages and how they help.
Paradigma FP y OOP usando técnicas avanzadas de Programación | Programacion A...Víctor Bolinches
Charla Universidad de Valencia - http://www.uv.es/
Cátedra de Capgemini 2016/17 - http://www.uv.es/capgeminiuv/sobre_nosotros.html
Asignatura : Programación avanzada y Lenguajes de programación
Título : Paradigma FP y OOP usando técnicas avanzadas de Programación
A Recovering Java Developer Learns to GoMatt Stine
As presented at OSCON 2014.
The Go programming language has emerged as a favorite tool of DevOps and cloud practitioners alike. In many ways, Go is more famous for what it doesn’t include than what it does, and co-author Rob Pike has said that Go represents a “less is more” approach to language design.
The Cloud Foundry engineering teams have steadily increased their use of Go for building components, starting with the Router, and progressing through Loggregator, the CLI, and more recently the Health Manager. As a “recovering-Java-developer-turned-DevOps-junkie” focused on helping our customers and community succeed with Cloud Foundry, it became very clear to me that I needed to add Go to my knowledge portfolio.
This talk will introduce Go and its distinctives to Java developers looking to add Go to their toolkits. We’ll cover Go vs. Java in terms of:
* type systems
* modularity
* programming idioms
* object-oriented constructs
* concurrency
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Tudor Dragan
Kotlin is a powerful language, but it also comes with its traps and pitfalls. This presentation is about uncovering the very nice features and strange particularities that the language has to offer.
Developer practices for traditional and agile Java development are well understood and documented. But dynamic languages (Groovy, Ruby, and others) change the ground rules. Many of the common practices, refactoring techniques, and design patterns we have been taught either no longer apply or should be applied differently and some new techniques also come into play. In this talk, we'll relearn practices needed for dynamic languages. Along the way we will look at typing, design patterns,
refactoring, functional style, SOLID principles revisited and more.
Leveraging the language, Use and abuse of Design Patterns, Web Services, Writing DSLs, Groovy Testing, Polyglot Groovy, Parallel Processing, Enterprise Groovy
Using the Groovy dynamic language for primarily functional / acceptance / customer / BDD testing with a forward looking perspective. Also considers polyglot options. The techniques and lessons learned can be applied to other kinds of testing and are also applicable to similar languages. Drivers and Runners discussed include: Native Groovy, HttpBuilder, HtmlUnit, WebTest, Watij, Selenium, WebDriver, Tellurium, JWebUnit, JUnit, TestNG, Spock, EasyB, JBehave, Cucumber, Robot Framework and FitNesse/Slim. Also looks at JMeter, ScalaCheck, Choco, AllPairs and ModelJUnit
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Transcript: Selling digital books in 2024: Insights from industry leaders - T...BookNet Canada
The publishing industry has been selling digital audiobooks and ebooks for over a decade and has found its groove. What’s changed? What has stayed the same? Where do we go from here? Join a group of leading sales peers from across the industry for a conversation about the lessons learned since the popularization of digital books, best practices, digital book supply chain management, and more.
Link to video recording: https://bnctechforum.ca/sessions/selling-digital-books-in-2024-insights-from-industry-leaders/
Presented by BookNet Canada on May 28, 2024, with support from the Department of Canadian Heritage.
Connector Corner: Automate dynamic content and events by pushing a buttonDianaGray10
Here is something new! In our next Connector Corner webinar, we will demonstrate how you can use a single workflow to:
Create a campaign using Mailchimp with merge tags/fields
Send an interactive Slack channel message (using buttons)
Have the message received by managers and peers along with a test email for review
But there’s more:
In a second workflow supporting the same use case, you’ll see:
Your campaign sent to target colleagues for approval
If the “Approve” button is clicked, a Jira/Zendesk ticket is created for the marketing design team
But—if the “Reject” button is pushed, colleagues will be alerted via Slack message
Join us to learn more about this new, human-in-the-loop capability, brought to you by Integration Service connectors.
And...
Speakers:
Akshay Agnihotri, Product Manager
Charlie Greenberg, Host
Let's dive deeper into the world of ODC! Ricardo Alves (OutSystems) will join us to tell all about the new Data Fabric. After that, Sezen de Bruijn (OutSystems) will get into the details on how to best design a sturdy architecture within ODC.
"Impact of front-end architecture on development cost", Viktor TurskyiFwdays
I have heard many times that architecture is not important for the front-end. Also, many times I have seen how developers implement features on the front-end just following the standard rules for a framework and think that this is enough to successfully launch the project, and then the project fails. How to prevent this and what approach to choose? I have launched dozens of complex projects and during the talk we will analyze which approaches have worked for me and which have not.
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
PHP Frameworks: I want to break free (IPC Berlin 2024)Ralf Eggert
In this presentation, we examine the challenges and limitations of relying too heavily on PHP frameworks in web development. We discuss the history of PHP and its frameworks to understand how this dependence has evolved. The focus will be on providing concrete tips and strategies to reduce reliance on these frameworks, based on real-world examples and practical considerations. The goal is to equip developers with the skills and knowledge to create more flexible and future-proof web applications. We'll explore the importance of maintaining autonomy in a rapidly changing tech landscape and how to make informed decisions in PHP development.
This talk is aimed at encouraging a more independent approach to using PHP frameworks, moving towards a more flexible and future-proof approach to PHP development.
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...DanBrown980551
Do you want to learn how to model and simulate an electrical network from scratch in under an hour?
Then welcome to this PowSyBl workshop, hosted by Rte, the French Transmission System Operator (TSO)!
During the webinar, you will discover the PowSyBl ecosystem as well as handle and study an electrical network through an interactive Python notebook.
PowSyBl is an open source project hosted by LF Energy, which offers a comprehensive set of features for electrical grid modelling and simulation. Among other advanced features, PowSyBl provides:
- A fully editable and extendable library for grid component modelling;
- Visualization tools to display your network;
- Grid simulation tools, such as power flows, security analyses (with or without remedial actions) and sensitivity analyses;
The framework is mostly written in Java, with a Python binding so that Python developers can access PowSyBl functionalities as well.
What you will learn during the webinar:
- For beginners: discover PowSyBl's functionalities through a quick general presentation and the notebook, without needing any expert coding skills;
- For advanced developers: master the skills to efficiently apply PowSyBl functionalities to your real-world scenarios.
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
Are you looking to streamline your workflows and boost your projects’ efficiency? Do you find yourself searching for ways to add flexibility and control over your FME workflows? If so, you’re in the right place.
Join us for an insightful dive into the world of FME parameters, a critical element in optimizing workflow efficiency. This webinar marks the beginning of our three-part “Essentials of Automation” series. This first webinar is designed to equip you with the knowledge and skills to utilize parameters effectively: enhancing the flexibility, maintainability, and user control of your FME projects.
Here’s what you’ll gain:
- Essentials of FME Parameters: Understand the pivotal role of parameters, including Reader/Writer, Transformer, User, and FME Flow categories. Discover how they are the key to unlocking automation and optimization within your workflows.
- Practical Applications in FME Form: Delve into key user parameter types including choice, connections, and file URLs. Allow users to control how a workflow runs, making your workflows more reusable. Learn to import values and deliver the best user experience for your workflows while enhancing accuracy.
- Optimization Strategies in FME Flow: Explore the creation and strategic deployment of parameters in FME Flow, including the use of deployment and geometry parameters, to maximize workflow efficiency.
- Pro Tips for Success: Gain insights on parameterizing connections and leveraging new features like Conditional Visibility for clarity and simplicity.
We’ll wrap up with a glimpse into future webinars, followed by a Q&A session to address your specific questions surrounding this topic.
Don’t miss this opportunity to elevate your FME expertise and drive your projects to new heights of efficiency.
3. Tic Tac Toe
• Players take it in turn to
place “marks” on the
board
• By convention, Player 1
uses “X” and starts
first; Player 2 uses “O”
• The game finishes once
one of the players has
three of their marks in a
row
• Also called noughts
and crosses (and other
names) with 4 x 4, 3D
and other variants
4. Challenge: Tic Tac Toe API
• move: given a board and position returns a
board with the current player at that position
– Can only be called on a board that is in-play; calling move on a
game board that is finished is a compile-time type error
• whoWon: given a finished board indicates if the
game was a draw or which player won
– Can only be called on a board that is finished; calling whoWon
on a game board that is in-play is a compile-time type error
• takeBack: takes either a finished board or a
board in-play that has had at least one move
and returns a board in-play
– It is a compile-time type error when used on an empty board
• playerAt: takes any board and position and
returns the (possible) player at the position
The main example for this talk is based on and inspired by:
https://github.com/tonymorris/course-answers/blob/master/src/TicTacToe/TicTacToe.md
5. But what’s this talk really about?
• Not really about solving/coding TicTacToe
• Looking at the Dynamic <-> Static typing
spectrum
• Looking at the OO <-> functional style
spectrum
• Looking at the pros and cons of different
programming styles
6. But what’s this talk really about?
• We all have the same goal
–Productively writing “bug-free”
maintainable code that “solves” some
real world users problem
–Types are one trick in my toolkit but I
also have tests, invariants
–Numerous ways to benefit from types
–Types are a burden on the programmer
–When writing DSLs, certain scripts,
certain test code, types may not justify
the burden
17. …Typing…
import groovy.transform.TypeChecked
import experimental.SprintfTypeCheckingVisitor
@TypeChecked(visitor=SprintfTypeCheckingVisitor)
void main() {
sprintf('%s will turn %d on %tF', 'John', new Date(), 21)
}
[Static type checking] - Parameter types didn't match types
expected from the format String:
For placeholder 2 [%d] expected 'int' but was 'java.util.Date'
For placeholder 3 [%tF] expected 'java.util.Date' but was 'int'
sprintf has an Object varargs
parameter, hence not normally
amenable to further static checking
but for constant Strings we can do
better using a custom type checking
plugin.
18. Show me the code
Type safe builder, phantom types, dependent types: Rocket, HList
25. Interlude: Solving Tic Tac Toe
• Use a game tree to
map out all possible
moves
• Solve the game tree
using brute force or
with various
optimisation
algorithms
26. Interlude: Tic Tac Toe game tree
Source: http://en.wikipedia.org/wiki/Game_tree
27. Interlude: Tic Tac Toe game tree
• Brute force
• Minimax
– Reduced
lookahead, e.g.
2 layers/plies
• Alpha beta pruning
– Improved efficiency
• Iterative deepening
– Often used with
alpha beta pruning
• But for Tic Tac Toe only 100s of
end states and 10s of thousands
of paths to get there
Source: http://en.wikipedia.org/wiki/Game_tree
29. Static Type Checking: Pluggable type system…
import groovy.transform.TypeChecked
import checker.BoringNameEliminator
@TypeChecked(visitor=BoringNameEliminator)
class Foo {
def method1() { 1 }
}
import groovy.transform.TypeChecked
import checker.BoringNameEliminator
@TypeChecked(visitor=BoringNameEliminator)
class Foo {
def method() { 1 }
}
[Static type checking] - Your method name is boring, I cannot allow it!
Groovy 2.1+
30. …Static Type Checking: Pluggable type system
package checker
import org.codehaus.groovy.ast.*
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.transform.stc.*
class BoringNameEliminator extends StaticTypeCheckingVisitor {
BoringNameEliminator(SourceUnit source, ClassNode cn,
TypeCheckerPluginFactory pluginFactory) {
super(source, cn, pluginFactory)
}
final message = "Your method name is boring, I cannot allow it!"
@Override void visitMethod(MethodNode node) {
super.visitMethod(node)
if ("method".equals(node.name) || "bar".equals(node.name)) {
addStaticTypeError(message, node)
}
}
}
Groovy 2.1+
31. …Typing…
import groovy.transform.TypeChecked
import tictactoe.*
Import static tictactoe.Position.*
@TypeChecked(visitor=TicTacToeTypeVisitor)
void main() {
Board.empty().move(NW).move(C).move(W).move(SW).move(SE)
}
package tictactoe
enum Position {
NW, N, NE, W, C, E, SW, S, SE
}
class Board {
static Board empty() { new Board() }
Board move(Position p) { this }
}
32. …Typing…
package tictactoe
import fj.*
import fj.data.List
import fj.data.Option
import fj.data.TreeMap
import static fj.P.p
import static fj.data.List.list
import static fj.data.List.nil
import static fj.data.Option.none
import static tictactoe.GameResult.Draw
import static tictactoe.Player.Player1
import static tictactoe.Player.toSymbol
import static tictactoe.Position.*
final class Board extends BoardLike {
private final List<P2<Position, Player>> moves
private final TreeMap<Position, Player> m
private static final Ord<Position> positionOrder = Ord.comparableOrd()
private Board(final List<P2<Position, Player>> moves, final TreeMap<Position, Player> m) {
this.moves = moves
this.m = m
}
Player whoseTurn() { moves.head()._2().alternate() }
boolean isEmpty() { false }
List<Position> occupiedPositions() { m.keys() }
int nmoves() { m.size() }
Option<Player> playerAt(Position pos) { m.get(pos) }
TakenBack takeBack() {
moves.isEmpty() ?
TakenBack.isEmpty() :
TakenBack.isBoard(new Board(moves.tail(), m.delete(moves.head()._1())))
}
@SuppressWarnings("unchecked")
MoveResult moveTo(final Position pos) {
final Player wt = whoseTurn()
final Option<Player> j = m.get(pos)
final TreeMap<Position, Player> mm = m.set(pos, wt)
final Board bb = new Board(moves.cons(p(pos, wt)), mm)
final List<P3<Position, Position, Position>> wins =
list(
p(NW, W, SW), p(N, C, S), p(NE, E, SE), p(NW, N, NE),
p(W, C, E), p(SW, S, SE), p(NW, C, SE), p(SW, C, NE)
)
final boolean isWin = wins.exists(new F<P3<Position, Position, Position>, Boolean>() {
public Boolean f(final P3<Position, Position, Position> abc) {
return list(abc._1(), abc._2(), abc._3()).mapMOption(mm.get()).exists(new F<List<Player>, Boolean>() {
public Boolean f(final List<Player> ps) {
return ps.allEqual(Equal.<Player> anyEqual())
}
})
}
})
final boolean isDraw = Position.positions().forall(new F<Position, Boolean>() {
Boolean f(final Position pos2) {
mm.contains(pos2)
}
})
j.isSome() ?
MoveResult.positionAlreadyOccupied() :
isWin ?
MoveResult.gameOver(new FinishedBoard(bb, GameResult.win(wt))) :
isDraw ?
MoveResult.gameOver(new FinishedBoard(bb, Draw)) :
MoveResult.keepPlaying(bb)
}
// …
// …
@Override
String toString() {
toString(new F2<Option<Player>, Position, Character>() {
Character f(final Option<Player> pl, final Position _) {
pl.option(p(' '), toSymbol)
}
}) + "n[ " + whoseTurn().toString() + " to move ]"
}
static final class EmptyBoard extends BoardLike {
private EmptyBoard() {}
@SuppressWarnings("unchecked")
Board moveTo(final Position pos) {
new Board(list(p(pos, Player1)), TreeMap.<Position, Player> empty(positionOrder).set(pos, Player1))
}
private static final EmptyBoard e = new EmptyBoard()
static EmptyBoard empty() { e }
Player whoseTurn() { Player1 }
boolean isEmpty() { true }
List<Position> occupiedPositions() { nil() }
int nmoves() { 0 }
Option<Player> playerAt(Position pos) { none() }
}
static final class FinishedBoard extends BoardLike {
private final Board b
private final GameResult r
private FinishedBoard(final Board b, final GameResult r) {
this.b = b
this.r = r
}
Board takeBack() {
b.takeBack().fold(
Bottom.<Board> error_("Broken invariant: board in-play with empty move list. This is a program bug"),
Function.<Board> identity()
)
}
Player whoseTurn() { b.whoseTurn() }
boolean isEmpty() { false }
List<Position> occupiedPositions() { b.occupiedPositions() }
int nmoves() { b.nmoves() }
Option<Player> playerAt(final Position pos) { b.playerAt(pos) }
GameResult result() { r }
@Override
String toString() {
b.toString() + "n[[" + r.toString() + " ]]"
}
}
}
33. …Typing
import groovy.transform.TypeChecked
import tictactoe.*
Import static tictactoe.Position.*
@TypeChecked(visitor=TicTacToeTypeVisitor)
void main() {
Board.empty().move(NW).move(C).move(W).move(SW).move(SE)
}
package tictactoe
enum Position {
NW, N, NE, W, C, E, SW, S, SE
}
[Static type checking] - Attempt to call suboptimal
move SE not allowed [HINT: try NE]
Custom type checker which fails
compilation if programmer attempts
to code a suboptimal solution. Where
suboptimal means doesn’t agree with
what is returned by a minimax,
alpha-beta pruning, iterative
deepening solving engine.