whats new in groovy 2.0?
DESCRIPTION
Presentation on Groovy 2.0 given at the 33rd Degree conference in Krakow, Poland, in March 2012.TRANSCRIPT
![Page 1: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/1.jpg)
Main sponsor
What’s New in Groovy 2.0?Guillaume LaforgeGroovy project Manager
![Page 2: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/2.jpg)
@glaforge
Guillaume Laforge• Groovy Project Manager at VMware
• Initiator of the Grails framework• Creator of the Gaelyk
and Caelyf toolkits
• Co-author of Groovy in Action
• Follow me on...• My blog: http://glaforge.appspot.com• Twitter: @glaforge• Google+: http://gplus.to/glaforge
2
![Page 3: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/3.jpg)
@glaforge
Agenda
• What’s new in Groovy 1.8?–Nicer DSLs with command chains–Runtime performance improvements–GPars bundled for taming your multicores–Closure enhancements–Builtin JSON support–New AST transformations
3
![Page 4: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/4.jpg)
@glaforge
Agenda
• What’s cooking for Groovy 2.0?–Alignments with JDK 7
• Project Coin (small language changes)• Invoke Dynamic support
– Continued runtime performance improvements
–Static type checking–Static compilation–Modularity
4
![Page 5: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/5.jpg)
@glaforge
Command chains• A grammar improvement allowing you
to drop dots & parens when chaining method calls–an extended version of top-level statements like println
• Less dots, less parens allow you to –write more readable business rules–in almost plain English sentences
• (or any language, of course)
5
![Page 6: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/6.jpg)
@glaforge
Command chains
turn left then right
6
![Page 7: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/7.jpg)
@glaforge
Command chains
turn left then right
Alternation of method names
6
![Page 8: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/8.jpg)
@glaforge
Command chains
turn left then right
Alternation of method names
and parameters(even named ones)
6
![Page 9: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/9.jpg)
@glaforge
Command chains
turn left then right
6
![Page 10: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/10.jpg)
@glaforge
Command chains
turn left then right ( ). ( )
Equivalent to:
6
![Page 11: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/11.jpg)
Look Ma!No parens, no dots!
![Page 12: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/12.jpg)
@glaforge
Command chains
take 2.pills, of: chloroquinine, after: 6.hours
Before... we used to do...
8
![Page 13: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/13.jpg)
@glaforge
Command chains
take 2.pills, of: chloroquinine, after: 6.hours
Before... we used to do...
Normal argument
8
![Page 14: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/14.jpg)
@glaforge
Command chains
take 2.pills, of: chloroquinine, after: 6.hours
Before... we used to do...
Normal argument Named arguments
8
![Page 15: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/15.jpg)
@glaforge
Command chains
take 2.pills, of: chloroquinine, after: 6.hours
Before... we used to do...
Normal argument Named arguments
Woud call:
def take(Map m, Quantity q)
8
![Page 16: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/16.jpg)
@glaforge
Command chains
take 2 pills of chloroquinine after 6 hours
9
Now, even less punctuation!
![Page 17: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/17.jpg)
@glaforge
Command chains
take 2 pills of chloroquinine after 6 hours ( ). ( ). ( ). ( )
9
Now, even less punctuation!
![Page 18: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/18.jpg)
@glaforge
Command chains
// Java fluent API approachclass RegimenBuilder { ... def take(int n) { this.pills = n return this }
def pills(String of) { return this } ...}
10
![Page 19: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/19.jpg)
@glaforge
Command chains
// variable injectiondef (of, after, hours) = /*...*/ // implementing the DSL logicdef take(n) { [pills: { of -‐> [chloroquinine: { after -‐> ['6': { time -‐> }] }] }]}
// -‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐-‐take 2 pills of chloroquinine after 6 hours
{ }
11
![Page 20: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/20.jpg)
@glaforge
Command chains
12
![Page 21: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/21.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)
12
![Page 22: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/22.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
12
![Page 23: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/23.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuation
12
![Page 24: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/24.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
12
![Page 25: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/25.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structures
12
![Page 26: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/26.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
12
![Page 27: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/27.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parens
12
![Page 28: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/28.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
12
![Page 29: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/29.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of terms
12
![Page 30: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/30.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
12
![Page 31: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/31.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
( ). ( ). ( )
12
![Page 32: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/32.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
( ). ( ). ( )
( ). ( )
12
![Page 33: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/33.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
12
![Page 34: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/34.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
( ). . ( )
12
![Page 35: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/35.jpg)
@glaforge
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
// closure parameters for new control structuresgiven {} when {} then {}
// zero-‐arg methods require parensselect all unique() from names
// possible with an odd number of termstake 3 cookies
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
( ). . ( )
( ).
12
![Page 36: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/36.jpg)
@glaforge
Runtime performance improvements
• Significant runtime improvements for primitive type operations–classical Fibonacci example x13 faster!–closer to Java performance
• Some direct method calls on this
• More on performance later on
13
![Page 37: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/37.jpg)
@glaforge
GPars bundled• GPars is bundled
in the Groovy distribution
• GPars covers a wide range of parallel and concurrent paradigms–actors, fork/join, map/filter/reduce, dataflow, agents–parallel arrays, executors, STM, and more...
• And you can use it from plain Java as well!
14
![Page 38: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/38.jpg)
@glaforge
Closure enhancements• Closure annotation parameters
• Some more functional flavor–composition
• compose several closures into one single closure
–trampoline• avoid stack overflow errors for recursive algorithms
–memoization• remember the outcome of previous closure invocations
• Currying improvements
15
![Page 39: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/39.jpg)
@glaforge
Closure annotation parameters
16
@Retention(RetentionPolicy.RUNTIME)@interface Invariant { Class value() // a closure class} @Invariant({ number >= 0 })class Distance { float number String unit} def d = new Distance(number: 10, unit: "meters") def anno = Distance.getAnnotation(Invariant)def check = anno.value().newInstance(d, d)assert check(d)
{
![Page 40: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/40.jpg)
@glaforge
Closure annotation parameters
16
@Retention(RetentionPolicy.RUNTIME)@interface Invariant { Class value() // a closure class} @Invariant({ number >= 0 })class Distance { float number String unit} def d = new Distance(number: 10, unit: "meters") def anno = Distance.getAnnotation(Invariant)def check = anno.value().newInstance(d, d)assert check(d)
{Poor-man’s GContracts
![Page 41: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/41.jpg)
@glaforge
Builtin JSON support
• Consuming
• Producing
• Pretty-printing
17
![Page 42: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/42.jpg)
@glaforge
Builtin JSON support
18
import groovy.json.*
def payload = new URL( "http://github.../json/commits/...").text
def slurper = new JsonSlurper()def doc = slurper.parseText(payload)
doc.commits.message.each { println it }
![Page 43: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/43.jpg)
@glaforge
Builtin JSON support
19
import groovy.json.* def json = new JsonBuilder() json.person { name "Guillaume" age 34 pets "Hector", "Felix"} println json.toString()
![Page 44: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/44.jpg)
@glaforge
Builtin JSON support
19
import groovy.json.* def json = new JsonBuilder() json.person { name "Guillaume" age 34 pets "Hector", "Felix"} println json.toString()
{ "person": { "name": "Guillaume", "age": 34, "pets": [ "Hector", "Felix" ] }}
![Page 45: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/45.jpg)
@glaforge
Builtin JSON support
20
import groovy.json.* println JsonOutput.prettyPrint( '''{"person":{"name":"Guillaume","age":34,''' + '''"pets":["Hector","Felix"]}}''')
{ "person": { "name": "Guillaume", "age": 34, "pets": [ "Hector", "Felix" ] }}
![Page 46: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/46.jpg)
@glaforge
New AST transformations• @Log
• @Field
• @AutoClone• @AutoExternalizable
• @Canonical– @ToString, – @EqualsAndHashCode, – @TupleConstructor
• Controlling the execution of your code– @ThreadInterrupt, – @TimedInterrupt, – @ConditionalInterrupt
• @InheritConstructor
• @WithReadLock• @WithWriteLock
• @ListenerList
21
![Page 47: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/47.jpg)
@glaforge
@Log
• Four different loggers can be injected–@Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy
22
import groovy.util.logging.* @Logclass Car { Car() { log.info 'Car constructed' }} def c = new Car()
![Page 48: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/48.jpg)
@glaforge
@Log
• Four different loggers can be injected–@Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy
22
import groovy.util.logging.* @Logclass Car { Car() { log.info 'Car constructed' }} def c = new Car()
Guardedw/ an if
![Page 49: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/49.jpg)
@glaforge
• Your application may run user’s code–what if the code runs in infinite loops or for too long?–what if the code consumes too many resources?
23
Controlling code execution
![Page 50: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/50.jpg)
@glaforge
• Your application may run user’s code–what if the code runs in infinite loops or for too long?–what if the code consumes too many resources?
23
Controlling code execution
![Page 51: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/51.jpg)
@glaforge
• Your application may run user’s code–what if the code runs in infinite loops or for too long?–what if the code consumes too many resources?
• 3 new transforms at your rescue–@ThreadInterrupt: adds Thread#isInterrupted checks
so your executing thread stops when interrupted–@TimedInterrupt: adds checks in method and closure
bodies to verify it’s run longer than expected–@ConditionalInterrupt: adds checks with your own
conditional logic to break out from the user code
23
Controlling code execution
![Page 52: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/52.jpg)
@glaforge
@ThreadInterrupt
24
@ThreadInterruptimport groovy.transform.ThreadInterrupt while (true) {
// eat lots of CPU}
33
![Page 53: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/53.jpg)
@glaforge
@ThreadInterrupt
24
@ThreadInterruptimport groovy.transform.ThreadInterrupt while (true) {
// eat lots of CPU}
if (Thread.currentThread.isInterrupted()) throw new InterruptedException(){ }
33
![Page 54: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/54.jpg)
@glaforge
@ThreadInterrupt
• Two optional annotation parameters available–checkOnMethodStart (true by default)–applyToAllClasses (true by default)
24
@ThreadInterruptimport groovy.transform.ThreadInterrupt while (true) {
// eat lots of CPU}
if (Thread.currentThread.isInterrupted()) throw new InterruptedException(){ }
33
![Page 55: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/55.jpg)
@glaforge
@ToString• Provides a default toString() method to your types• Available annotation options
– includeNames, includeFields, includeSuper, excludes
25
import groovy.transform.ToString @ToStringclass Person { String name int age} println new Person(name: 'Pete', age: 15)// => Person(Pete, 15)
![Page 56: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/56.jpg)
@glaforge
@EqualsAndHashCode
• Provides default implementations for equals() and hashCode() methods
26
import groovy.transform.EqualsAndHashCode @EqualsAndHashCodeclass Coord { int x, y} def c1 = new Coord(x: 20, y: 5)def c2 = new Coord(x: 20, y: 5) assert c1 == c2assert c1.hashCode() == c2.hashCode()
![Page 57: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/57.jpg)
@glaforge
@TupleConstructor• Provides a «classical» constructor with all properties• Several annotation parameter options available
27
import groovy.transform.TupleConstructor @TupleConstructor class Person { String name int age} def m = new Person('Marion', 3) assert m.name == 'Marion'assert m.age == 3
![Page 58: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/58.jpg)
@glaforge
@Canonical
• One annotation to rule them all!–@Canonical mixes together
• @ToString• @EqualsAndHashCode• @TupleConstructor
• You can customize behavior by combining @Canonical and one of the other annotations
28
![Page 59: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/59.jpg)
@glaforge
@InheritConstructors
• Classes like Exception are painful when extended, as all the base constructors should be replicated
29
class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) }}
![Page 60: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/60.jpg)
@glaforge
@InheritConstructors
• Classes like Exception are painful when extended, as all the base constructors should be replicated
29
class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) }}
import groovy.transform.*
@InheritConstructorsclass CustomException extends Exception {
}
![Page 61: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/61.jpg)
@glaforge
Miscelanous• Compilation customizers • Java 7 diamond operator• Slashy and dollar slashy strings• New GDK methods• (G)String to Enum coercion• Customizing the Groovysh prompt• Executing remote scripts
30
![Page 62: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/62.jpg)
@glaforge
Compilation customizers• Ability to apply some customization to the Groovy
compilation process
• Three available customizers–ImportCustomizer–ASTTransformationCustomizer–SecureASTCustomizer
• But you can implement your own
31
![Page 63: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/63.jpg)
@glaforge
Imports customizer
32
def configuration = new CompilerConfiguration() def custo = new ImportCustomizer()custo.addStaticStar(Math.name)configuration.addCompilationCustomizers(custo) def result = new GroovyShell(configuration) // import static java.lang.Math.* .evaluate(" cos PI/3 ")
![Page 64: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/64.jpg)
@glaforge
Customizing the Groovysh prompt
33
![Page 65: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/65.jpg)
What’s cookingfor 2.0?
![Page 66: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/66.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 67: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/67.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 68: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/68.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 69: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/69.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 70: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/70.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 71: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/71.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 72: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/72.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 73: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/73.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
![Page 74: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/74.jpg)
@glaforge
Groovy 2.0 roadmap• Java 7 alignements: Project Coin
–binary literals–underscore in literals–multicatch
• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking • Static compilation
35
End of April?
![Page 75: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/75.jpg)
@glaforge
Java 7 / JDK 7
• Project Coin and InvokeDynamic
36
![Page 76: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/76.jpg)
@glaforge
Binary literals
• We had decimal, octal and hexadecimal notations for number literals
• We can now use binary representations too
37
int x = 0b10101111assert x == 175 byte aByte = 0b00100001assert aByte == 33 int anInt = 0b1010000101000101assert anInt == 41285
![Page 77: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/77.jpg)
@glaforge
Underscore in literals
• Now we can also add underscores in number literals for more readability
38
long creditCardNumber = 1234_5678_9012_3456Llong socialSecurityNumbers = 999_99_9999Lfloat monetaryAmount = 12_345_132.12long hexBytes = 0xFF_EC_DE_5Elong hexWords = 0xFFEC_DE5Elong maxLong = 0x7fff_ffff_ffff_ffffLlong alsoMaxLong = 9_223_372_036_854_775_807Llong bytes = 0b11010010_01101001_10010100_10010010
![Page 78: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/78.jpg)
@glaforge
Multicatch
• One block for multiple exception caught–rather than duplicating the block
39
try { /* ... */} catch(IOException | NullPointerException e) { /* one block to treat 2 exceptions */}
![Page 79: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/79.jpg)
@glaforge
InvokeDynamic• Groovy 2.0 supports JDK 7’s invokeDynamic
–compiler will have a flag for compiling against JDK 7–might use the invokeDynamic backport for < JDK 7
• Benefits–more runtime performance!
• at least as fast as current «dynamic» Groovy
–in the long run, will allow us to get rid of code!• call site caching, thanks to MethodHandles• metaclass registry, thanks to ClassValues• will let the JIT inline calls more easily
40
![Page 80: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/80.jpg)
@glaforge
Groovy Modularity• Groovy’s «all» JAR weighs in at 4MB
• Nobody needs everything–Template engine, Ant scripting, Swing UI building...
• Provide a smaller core–and several smaller JARs per feature
• Provide hooks for setting up DGM methods, etc.
41
![Page 81: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/81.jpg)
@glaforge
Static Type Checking• Goal: make the Groovy compiler «grumpy»!
–and throw compilation errors (not at runtime)• Not everybody needs dynamic features all the time
–think Java libraries scripting• Grumpy should...
–tell you about your method or variable typos–complain if you call methods that don’t exist–shout on assignments of wrong types–infer the types of your variables–figure out GDK methods–etc...
42
![Page 82: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/82.jpg)
@glaforge
Typos in your variable or method
43
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
![Page 83: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/83.jpg)
@glaforge
Typos in your variable or method
43
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
Compilationerrors!
![Page 84: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/84.jpg)
@glaforge
Typos in your variable or method
43
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
Compilationerrors!
Annotation can be atclass or method level
![Page 85: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/85.jpg)
@glaforge
Complain on wrong assignments
44
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() def o = new Object()int x = o String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
![Page 86: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/86.jpg)
@glaforge
Complain on wrong assignments
44
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() def o = new Object()int x = o String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
Compilationerrors!
![Page 87: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/87.jpg)
@glaforge
Complain on wrong return types
45
// checks if/else branch return valuesint method() { if (true) { 'String' } else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name}
![Page 88: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/88.jpg)
@glaforge
Complain on wrong return types
45
// checks if/else branch return valuesint method() { if (true) { 'String' } else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name}
Compilationerror!
![Page 89: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/89.jpg)
@glaforge
Type inference
46
@TypeChecked test() { def name = " Guillaume " // String type infered (even inside GString) println "NAME = ${name.toUpperCase()}" // Groovy GDK method support // (GDK operator overloading too) println name.trim() int[] numbers = [1, 2, 3] // Element n is an int for (int n in numbers) { println n }}
![Page 90: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/90.jpg)
@glaforge
Staticly checked & dyn. methods
47
@TypeCheckedString greeting(String name) { // call method with dynamic behavior // but with proper signature generateMarkup(name.toUpperCase())} // usual dynamic behaviorString generateMarkup(String name) { def sw = new StringWriter() new MarkupBuilder(sw).html { body { div name } } sw.toString()}
![Page 91: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/91.jpg)
@glaforge
Instanceof checks
48
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }
}
![Page 92: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/92.jpg)
@glaforge
Instanceof checks
48
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }
}
No needfor casts
![Page 93: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/93.jpg)
@glaforge
Instanceof checks
48
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }
}
No needfor casts
Can call String#multiply(int)from the Groovy Development Kit
![Page 94: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/94.jpg)
@glaforge
Lowest Upper Bound• Represents the lowest «super» type classes have
in common–may be virtual (aka «non-denotable»)
49
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
![Page 95: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/95.jpg)
@glaforge
Lowest Upper Bound• Represents the lowest «super» type classes have
in common–may be virtual (aka «non-denotable»)
49
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
Inferred return type:List<Number>
![Page 96: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/96.jpg)
@glaforge
Flow typing• Static type checking shouldn’t complain even for
bad coding practicies which work w/o type checks
50
@TypeChecked test() { def var = 123 // inferred type is int int x = var // var is an int var = "123" // assign var with a String
x = var.toInteger() // no problem, no need to cast
var = 123 x = var.toUpperCase() // error, var is int!}
![Page 97: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/97.jpg)
@glaforge
Gotchas: static checking vs dynamic• Type checking works at compile-time
–adding @TypeChecked doesn’t change behavior• do not confuse with static compilation
• Most dynamic features cannot be type checked–metaclass changes, categories–dynamically bound variables (ex: script’s binding)
• However, compile-time metaprogramming works–as long as proper type information is defined
51
![Page 98: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/98.jpg)
@glaforge
Gotchas: runtime metaprogramming
52
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
![Page 99: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/99.jpg)
@glaforge
Gotchas: runtime metaprogramming
52
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
Not allowed:metaClass property
is dynamic
![Page 100: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/100.jpg)
@glaforge
Gotchas: runtime metaprogramming
52
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
Not allowed:metaClass property
is dynamic
Method notrecognized
![Page 101: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/101.jpg)
@glaforge
Gotchas: closures need explicit types
• A «Groovy Enhancement Proposal» to address this issue
53
@TypeChecked test() { ["a", "b", "c"].collect { it.toUpperCase() // Not OK }}
![Page 102: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/102.jpg)
@glaforge
Gotchas: closures need explicit types
• A «Groovy Enhancement Proposal» to address this issue
53
@TypeChecked test() { ["a", "b", "c"].collect { String it -‐> it.toUpperCase() // OK, it’s a String }}
![Page 103: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/103.jpg)
@glaforge
Closure shared variables
54
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
![Page 104: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/104.jpg)
@glaforge
Closure shared variables
54
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
var assigned in the closure:«shared closure variable»
![Page 105: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/105.jpg)
@glaforge
Closure shared variables
54
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
var assigned in the closure:«shared closure variable»
Impossible to ensure the assignment really happens
![Page 106: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/106.jpg)
@glaforge
Closure shared variables
54
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
var assigned in the closure:«shared closure variable»
Impossible to ensure the assignment really happens
Only methods of the most specific compatible type (LUB)are allowed by the type checker
![Page 107: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/107.jpg)
@glaforge
Closure shared variables
55
class A { void foo() {} }class B extends A { void bar() {} }
@TypeChecked test() { def var = new A() def cl = { var = new B() } cl() var.foo() // OK!}
![Page 108: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/108.jpg)
@glaforge
Closure shared variables
55
class A { void foo() {} }class B extends A { void bar() {} }
@TypeChecked test() { def var = new A() def cl = { var = new B() } cl() var.foo() // OK!}
var is at leastan instance of A
![Page 109: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/109.jpg)
@glaforge
Static Compilation
• Given your Groovy code can be type checked...we can as well compile it «statically»
–ie. generate the same byte code as javac
56
![Page 110: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/110.jpg)
@glaforge
Static Compilation: advantages• You gain:
–Type safety• thanks to static type checking
– static compilation builds upon static type checking
–Faster code• as close to Java’s performance as possible
–Code immune to «monkey patching»• metaprogramming badly used can interfere with framework code
–Smaller bytecode size
57
![Page 111: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/111.jpg)
@glaforge
Static Compilation: disadvantages• But you loose:
–Dynamic features• metaclass changes, categories, etc.
–Dynamic method dispatch• although emulated as close as possible to «dynamic» Groovy
58
![Page 112: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/112.jpg)
@glaforge
Staticly compiled & dyn. methods
59
@CompileStaticString greeting(String name) { // call method with dynamic behavior // but with proper signature generateMarkup(name.toUpperCase())} // usual dynamic behaviorString generateMarkup(String name) { def sw = new StringWriter() new MarkupBuilder(sw).html { body { div name } } sw.toString()}
![Page 113: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/113.jpg)
@glaforge
What about performance?• Comparisons between:
–Java
–Groovy static compilation• ie. Groovy 2.0
–Groovy with primitive optimizations• ie. since Groovy 1.8
–Groovy without optimizations• ie. Groovy 1.7 and before
60
![Page 114: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/114.jpg)
@glaforge
What about performance?
61
Fibonacci Pi (π) quadrature
Binarytrees
Java
StaMccompilaMon
PrimiMve opMmizaMons
No prim.opMmizaMons
140 ms 93 ms 4.5 s
150 ms 220 ms 7.6 s
270 ms 110 ms 29.6 s
3800 ms 3.8 s 50.0 s1.7
1.8
2.0
![Page 115: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/115.jpg)
@glaforge
Summary• Main themes of the Groovy 2.0 release
–Modularity
–Embark the JDK 7 enhancements• Project Coin• Invoke Dynamic
–Static aspects• Static type checking• Static compilation
62
![Page 116: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/116.jpg)
@glaforge
Summary
63
ROCKS!
![Page 117: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/117.jpg)
@glaforge
Thank you!
Guillaume Laforge
Head of Groovy Development
Email: [email protected]
Twitter: @glaforge
Google+: http://gplus.to/glaforge
Blog: http://glaforge.appspot.com
64
![Page 118: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/118.jpg)
Q&AGot questions,
really?
![Page 119: Whats new in Groovy 2.0?](https://reader035.vdocuments.site/reader035/viewer/2022062418/55587551d8b42a8d018b52ac/html5/thumbnails/119.jpg)
@glaforge
Image credits• Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg
• Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2
• Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg
• Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg
• Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/
• Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg
• Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg
• Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg
• Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg
• Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg
• Caution: http://www.jeunes-epinay-sur-seine.fr/wp-content/uploads/2010/11/caution-colocation.jpg
• Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg
• Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg
• Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg
• Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg
• WIP: http://www.connetport.com/wp-content/uploads/Work_in_progress.svg_.png
• Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg
•
66