Download - Groovy 1.8 et 2.0 au BreizhC@mp 2012
![Page 1: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/1.jpg)
Groovy 2.0What’s up doc?
Guillaume LaforgeGroovy Project Manager
@glaforge
1
Cédric ChampeauGroovy Committer@cedricchampeau
![Page 2: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/2.jpg)
Groovy 2.0What’s up doc?
Guillaume LaforgeGroovy Project Manager
@glaforge
1
Cédric ChampeauGroovy Committer@cedricchampeau
![Page 3: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/3.jpg)
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/glaforge2
![Page 4: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/4.jpg)
Cédric Champeau
• Past: Groovy contributor then committer
• Present: Groovy Core Developer at VMware
• bug fixes with main focus on static type checking and static compilation
• Follow me on...
• My blog: http://jroller.com/melix
• Twitter: @cedricchampeau
• Google+: http://gplus.to/cchampeau3
![Page 5: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/5.jpg)
Agenda (1/2)
• 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
4
![Page 6: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/6.jpg)
Agenda (2/2)
• What’s cooking for Groovy 2.0?
• Modularity
• Alignments with JDK 7
• Project Coin (small language changes)
• Invoke Dynamic support
• Continued runtime performance improvements
• Static type checking
• Static compilation
5
![Page 7: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/7.jpg)
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)
6
![Page 8: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/8.jpg)
Command chains
pull request on github
7
![Page 9: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/9.jpg)
Command chains
pull request on github
Alternation of method names
7
![Page 10: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/10.jpg)
Command chains
pull request on github
Alternation of method names
and parameters(even named ones)
7
![Page 11: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/11.jpg)
Command chains
pull request on github
7
![Page 12: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/12.jpg)
Command chains
pull request on github ( ). ( )
Equivalent to:
7
![Page 13: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/13.jpg)
Command chains
8
commit 2 changes on master branch
![Page 14: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/14.jpg)
Command chains
8
commit 2 changes on master branch ( ). ( ). ( )
![Page 15: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/15.jpg)
Command chains
9
![Page 16: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/16.jpg)
Command chains
// methods with multiple arguments (commas)
9
![Page 17: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/17.jpg)
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
9
![Page 18: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/18.jpg)
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuation
9
![Page 19: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/19.jpg)
Command chains
// methods with multiple arguments (commas)take coffee with sugar, milk and liquor
// leverage named-‐args as punctuationcheck that: margarita tastes good
9
![Page 20: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/20.jpg)
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
9
![Page 21: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/21.jpg)
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 {}
9
![Page 22: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/22.jpg)
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
9
![Page 23: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/23.jpg)
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
9
![Page 24: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/24.jpg)
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
9
![Page 25: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/25.jpg)
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
9
![Page 26: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/26.jpg)
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
( ). ( ). ( )
9
![Page 27: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/27.jpg)
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
( ). ( ). ( )
( ). ( )
9
![Page 28: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/28.jpg)
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
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
9
![Page 29: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/29.jpg)
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
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
( ). . ( )
9
![Page 30: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/30.jpg)
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
( ). ( ). ( )
( ). ( )
( ). ( ). ( )
( ). . ( )
( ).
9
![Page 31: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/31.jpg)
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!
10
![Page 32: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/32.jpg)
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
11
![Page 33: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/33.jpg)
Closure annotation parameters
12
@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 34: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/34.jpg)
Closure annotation parameters
12
@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 35: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/35.jpg)
Closure memoization
13
![Page 36: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/36.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
![Page 37: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/37.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000ms
![Page 38: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/38.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediately
![Page 39: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/39.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000ms
![Page 40: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/40.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately
![Page 41: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/41.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately
![Page 42: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/42.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cached
![Page 43: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/43.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10)
![Page 44: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/44.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10)
![Page 45: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/45.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10) // at most 10 invocations cached
![Page 46: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/46.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10) // at most 10 invocations cacheddef plusAtMost = { ... }.memoizeAtMost(10)
![Page 47: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/47.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10) // at most 10 invocations cacheddef plusAtMost = { ... }.memoizeAtMost(10)
// between 10 and 20 invocations cached
![Page 48: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/48.jpg)
Closure memoization
13
def plus = { a, b -‐> sleep 1000; a + b }.memoize()
assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediatelyassert plus(2, 2) == 4 // after 1000msassert plus(2, 2) == 4 // return immediately // at least 10 invocations cacheddef plusAtLeast = { ... }.memoizeAtLeast(10) // at most 10 invocations cacheddef plusAtMost = { ... }.memoizeAtMost(10)
// between 10 and 20 invocations cacheddef plusAtLeast = { ... }.memoizeBetween(10, 20)
![Page 49: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/49.jpg)
Builtin JSON support
• Consuming
• Producing
• Pretty-printing
14
![Page 50: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/50.jpg)
Builtin JSON support
15
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 51: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/51.jpg)
Builtin JSON support
16
import groovy.json.* def json = new JsonBuilder() json.person { name "Guillaume" age 34 pets "Hector", "Felix"} println json.toString()
![Page 52: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/52.jpg)
Builtin JSON support
16
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 53: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/53.jpg)
Builtin JSON support
17
import groovy.json.* println JsonOutput.prettyPrint( '''{"person":{"name":"Guillaume","age":34,''' + '''"pets":["Hector","Felix"]}}''')
{ "person": { "name": "Guillaume", "age": 34, "pets": [ "Hector", "Felix" ] }}
![Page 54: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/54.jpg)
New AST transformations
• @Log
• @Field
• @AutoClone
• @AutoExternalizable
• @Canonical• @ToString
• @EqualsAndHashCode
• @TupleConstructor
• Controlling execution• @ThreadInterrupt
• @TimedInterrupt
• @ConditionalInterrupt
• @InheritConstructor
• @WithReadLock
• @WithWriteLock
• @ListenerList
18
![Page 55: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/55.jpg)
@Log
• Four different loggers can be injected
• @Log
• @Commons
• @Log4j
• @Slf4j
• Possible to implement your own strategy
19
import groovy.util.logging.* @Logclass Car { Car() { log.info 'Car constructed' }} def c = new Car()
![Page 56: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/56.jpg)
@Log
• Four different loggers can be injected
• @Log
• @Commons
• @Log4j
• @Slf4j
• Possible to implement your own strategy
19
import groovy.util.logging.* @Logclass Car { Car() { log.info 'Car constructed' }} def c = new Car()
Guardedw/ an if
![Page 57: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/57.jpg)
Controlling code execution
• 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
20
![Page 58: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/58.jpg)
@ThreadInterrupt
21
@ThreadInterruptimport groovy.transform.ThreadInterrupt while (true) {
// eat lots of CPU}
33
![Page 59: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/59.jpg)
@ThreadInterrupt
21
@ThreadInterruptimport groovy.transform.ThreadInterrupt while (true) {
// eat lots of CPU}
if (Thread.currentThread().isInterrupted()) throw new InterruptedException(){ }
33
![Page 60: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/60.jpg)
@ToString
• Provides a default toString() method to your types
• Available annotation options• includeNames, includeFields, includeSuper, excludes
22
import groovy.transform.ToString @ToStringclass Person { String name int age} println new Person(name: 'Pete', age: 15)// => Person(Pete, 15)
![Page 61: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/61.jpg)
@EqualsAndHashCode
• Provides default implementations for equals() and hashCode() methods
23
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 62: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/62.jpg)
@TupleConstructor
• Provides a «classical» constructor with all properties
• Several annotation parameter options available
24
import groovy.transform.TupleConstructor @TupleConstructor class Person { String name int age} def m = new Person('Marion', 4) assert m.name == 'Marion'assert m.age == 4
![Page 63: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/63.jpg)
@InheritConstructors
• Classes like Exception are painful when extended, as all the base constructors should be replicated
25
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 64: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/64.jpg)
@InheritConstructors
• Classes like Exception are painful when extended, as all the base constructors should be replicated
25
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 65: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/65.jpg)
Miscellaneous
• 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
26
![Page 66: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/66.jpg)
Compilation customizers
• Ability to apply some customization to the Groovy compilation process
• Three available customizers
• ImportCustomizer
• ASTTransformationCustomizer
• SecureASTCustomizer
• But you can implement your own
27
![Page 67: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/67.jpg)
Imports customizer
28
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 68: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/68.jpg)
What’s in storefor 2.0?
![Page 69: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/69.jpg)
2.0
Around the corner...
![Page 70: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/70.jpg)
Groovy 2.0
• A more modular Groovy
• Java 7 alignements: Project Coin
• binary literals
• underscore in literals
• multicatch
• JDK 7: InvokeDynamic
• Static type checking
• Static compilation
31
![Page 71: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/71.jpg)
Groovy Modularity
• Groovy’s «all» JAR weighs in at 6 MB
• 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.
32
![Page 72: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/72.jpg)
The new JARs
• A smaller groovy.jar: 3MB
• Modules
• console
• docgenerator
• groovydoc
• groovysh
• ant
• bsf
• jsr-223
• jmx
• sql
• swing
• servlet
• templates
• test
• testng
• json
• xml33
![Page 73: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/73.jpg)
Extension modules
• Create your own module
• contribute instance extension methods
34
package foo
class StringExtension { static introduce(String self, String name) { "Hi ${name), I’m ${self}" }}
// usage: "Guillaume".introduce("Cédric")
![Page 74: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/74.jpg)
Extension modules
• Create your own module
• contribute instance extension methods
34
package foo
class StringExtension { static introduce(String self, String name) { "Hi ${name), I’m ${self}" }}
// usage: "Guillaume".introduce("Cédric")
Same structureas Categories
![Page 75: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/75.jpg)
Extension modules
• Create your own module
• contribute class extension methods
35
package foo
class StaticStringExtension { static hi(String self) { "Hi!" }}
// usage: String.hi()
![Page 76: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/76.jpg)
Extension module descriptor
• Descriptor in: META-INF/services/org.codehaus.groovy.runtime.ExtensionModule
36
moduleName = stringExtensionsmoduleVersion = 1.0// comma-‐separated list of classesextensionClasses = foo.StringExtension// comma-‐separated list of classesstaticExtensionClasses = foo.StaticStringExtension
![Page 77: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/77.jpg)
Java 7 / JDK 7
• Project Coin and InvokeDynamic
37
![Page 78: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/78.jpg)
Binary literals
• We had decimal, octal and hexadecimal notations for number literals
• We can now use binary representations too
38
int x = 0b10101111assert x == 175 byte aByte = 0b00100001assert aByte == 33 int anInt = 0b1010000101000101assert anInt == 41285
![Page 79: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/79.jpg)
Underscore in literals
• Now we can also add underscores in number literals for more readability
39
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 80: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/80.jpg)
Multicatch
• One block for multiple exception caught
• rather than duplicating the block
40
try { /* ... */} catch(IOException | NullPointerException e) { /* one block to treat 2 exceptions */}
![Page 81: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/81.jpg)
InvokeDynamic
• Groovy 2.0 supports JDK 7’s invokeDynamic
• compiler has 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 easily41
![Page 82: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/82.jpg)
42
Your turn!
![Page 83: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/83.jpg)
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...43
![Page 84: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/84.jpg)
Typos in a vars or methods
44
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
![Page 85: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/85.jpg)
Typos in a vars or methods
44
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 86: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/86.jpg)
Typos in a vars or methods
44
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 87: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/87.jpg)
Wrong assignments
45
// 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 88: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/88.jpg)
Wrong assignments
45
// 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 89: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/89.jpg)
Wrong return types
46
// checks if/else branch return values@TypeCheckedint method() { if (true) { 'String' } else { 42 }}// works for switch/case & try/catch/finally // transparent toString() implied@TypeCheckedString greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name}
![Page 90: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/90.jpg)
Wrong return types
46
// checks if/else branch return values@TypeCheckedint method() { if (true) { 'String' } else { 42 }}// works for switch/case & try/catch/finally // transparent toString() implied@TypeCheckedString greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name}
Compilationerror!
![Page 91: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/91.jpg)
Type inference
47
@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 92: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/92.jpg)
Statically checked & dyn meth
48
@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 93: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/93.jpg)
Instanceof checks
49
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }
}
![Page 94: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/94.jpg)
Instanceof checks
49
@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 95: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/95.jpg)
Instanceof checks
49
@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 96: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/96.jpg)
Lowest Upper Bound
• Represents the lowest «super» type classes have in common
• may be virtual (aka «non-denotable»)
50
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
![Page 97: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/97.jpg)
Lowest Upper Bound
• Represents the lowest «super» type classes have in common
• may be virtual (aka «non-denotable»)
50
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
Inferred return type:List<Number & Comparable>
![Page 98: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/98.jpg)
Lowest Upper Bound
• Represents the lowest «super» type classes have in common
• may be virtual (aka «non-denotable»)
50
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
Inferred return type:List<Number & Comparable>
![Page 99: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/99.jpg)
Flow typing
• Static type checking shouldn’t complain even for bad coding practicies which work without type checks
51
@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 100: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/100.jpg)
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
52
![Page 101: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/101.jpg)
Runtime metaprogramming
53
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
![Page 102: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/102.jpg)
Runtime metaprogramming
53
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
Not allowed:metaClass property
is dynamic
![Page 103: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/103.jpg)
Runtime metaprogramming
53
@TypeChecked void test() { Integer.metaClass.foo = {} 123.foo()}
Not allowed:metaClass property
is dynamic
Method notrecognized
![Page 104: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/104.jpg)
Explicit type for closures
• A « Groovy Enhancement Proposal » to address the issue
54
@TypeChecked test() { ["a", "b", "c"].collect { it.toUpperCase() // Not OK }}
![Page 105: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/105.jpg)
Explicit type for closures
• A « Groovy Enhancement Proposal » to address the issue
54
@TypeChecked test() { ["a", "b", "c"].collect { String it -‐> it.toUpperCase() // OK, it’s a String }}
![Page 106: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/106.jpg)
Closure shared variables
55
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
![Page 107: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/107.jpg)
Closure shared variables
55
@TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK!}
var assigned in the closure:«shared closure variable»
![Page 108: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/108.jpg)
Closure shared variables
55
@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 109: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/109.jpg)
Closure shared variables
55
@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 110: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/110.jpg)
Closure shared variables
56
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 111: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/111.jpg)
Closure shared variables
56
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 112: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/112.jpg)
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
• Also interesting for those stuck in JDK < 7 to benefit from performance improvements
57
![Page 113: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/113.jpg)
Advantages
• You gain:
• Type safety
• thanks to static type checking
• static compilation builds upon static type checking
• Faster code
• as close as possible to Java’s performance
• Code immune to «monkey patching»
• metaprogramming badly used can interfere with framework code
• Smaller bytecode size58
![Page 114: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/114.jpg)
Disadvantages
• But you loose:
• Dynamic features
• metaclass changes, categories, etc.
• Dynamic method dispatch
• although as close as possible to «dynamic» Groovy
59
![Page 115: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/115.jpg)
Statically compiled & dyn meth
60
@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 116: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/116.jpg)
What about performance?
• Comparisons between:
• Java
• Groovy static compilation (Groovy 2.0)
• Groovy with primitive optimizations (Groovy 1.8+)
• Groovy without optimizations (Groovy 1.7)
61
![Page 117: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/117.jpg)
What about performance?
62
Fibonacci Pi (π) quadrature
Binarytrees
Java
Staticcompilation
Primitive optimizations
No prim.optimizations
188 ms 97 ms 3.6 s
202 ms 101 ms 4.4 s
360 ms 111 ms 23.7 s
2590 ms 3220 ms 50.0 s1.7
1.8
2.0
![Page 118: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/118.jpg)
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
63
![Page 119: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/119.jpg)
64
![Page 120: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/120.jpg)
Thank you!
Guillaume Laforge
Head of Groovy Development
Email: [email protected]
Twitter: @glaforge
Google+: http://gplus.to/glaforge
Blog: http://glaforge.appspot.com
65
Cédric Champeau
Groovy Core Committer
Email: [email protected]
Twitter: @cedricchampeau
Google+: http://gplus.to/cchampeau
Blog: http://jroller.com/melix
![Page 121: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/121.jpg)
Questions & Answers
• Got questions, really?
66
Q&A
![Page 122: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/122.jpg)
Image credits
• Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg
• 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
• Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.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
• Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg
• Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg
• Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg
• Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg
• Around the corner: http://3.bp.blogspot.com/-wvfO5NUbi8Q/TzBqTh4SOsI/AAAAAAAADOg/lRE9XVHGiOc/s1600/around-the-corner_large.jpg
• Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg
67
![Page 123: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/123.jpg)
1 // methods with multiple arguments (commas) 2 take coffee with sugar, milk and liquor 3 4 // leverage named-args as punctuation 5 check that: margarita tastes good 6 7 // closure parameters for new control structures 8 given {} when {} then {} 9 10 // zero-arg methods require parens11 select all unique() from names12 13 // possible with an odd number of terms14 take 3 cookies
@GrabAST TransformGroovy 1.8
![Page 124: Groovy 1.8 et 2.0 au BreizhC@mp 2012](https://reader033.vdocuments.net/reader033/viewer/2022060109/55587468d8b42aaa7e8b5340/html5/thumbnails/124.jpg)
1 // methods with multiple arguments (commas) 2 take coffee with sugar, milk and liquor 3 4 // leverage named-args as punctuation 5 check that: margarita tastes good 6 7 // closure parameters for new control structures 8 given {} when {} then {} 9 10 // zero-arg methods require parens11 select all unique() from names12 13 // possible with an odd number of terms14 take 3 cookies
Need parens there!
@GrabAST TransformGroovy 1.8