lift off with groovy 2 at javaone 2013
DESCRIPTION
Presentations on the features of the Groovy 2.x lineTRANSCRIPT
![Page 1: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/1.jpg)
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
Guillaume Laforge @glaforge
Lift-off with Groovy 2 ...and beyond!
![Page 2: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/2.jpg)
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
Guillaume Laforge @glaforge
Lift-off with Groovy 2 ...and beyond!
![Page 3: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/3.jpg)
Guillaume Laforge @glaforge
http://glaforge.appspot.com http://gplus.to/glaforge
![Page 4: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/4.jpg)
Guillaume Laforge @glaforge
http://glaforge.appspot.com http://gplus.to/glaforge
Presentation will be uploaded tohttps://speakerdeck.com/glaforge
![Page 5: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/5.jpg)
A dynamic language,optionally typed
Groovy
![Page 6: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/6.jpg)
...statically type checkedand compiled as needed
Groovy
![Page 7: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/7.jpg)
Syntax deriving from Java, thus easy to learn
Groovy
![Page 8: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/8.jpg)
million downloadsin 2012
1.7
![Page 9: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/9.jpg)
![Page 10: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/10.jpg)
10
![Page 11: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/11.jpg)
A blossomingEcosystem
![Page 12: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/12.jpg)
![Page 13: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/13.jpg)
![Page 14: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/14.jpg)
![Page 15: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/15.jpg)
![Page 16: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/16.jpg)
GVM
![Page 17: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/17.jpg)
Let’s start the engine
ModularityJava 7: Project Coin & invoke dynamicStatic type checking & compilation
![Page 18: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/18.jpg)
Modularity
« Not everybody needs everything,all the time, at the same time! »
![Page 19: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/19.jpg)
Groovy modularity
• The « groovy-all » weighted... 6 MB !
• In addition to the language, we have APIs:– template engine, Ant task scripting, Swing UI builder,
JMX builder...
• We want a lighter « core »– with APIs in the form of modules
• Ability to wire in « extension methods »
16
![Page 20: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/20.jpg)
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console– docgenerator– groovydoc– groovysh– ant– bsf
– jsr-223– jmx– sql– swing– servlet– templates
– test– testng– json– xml
17
![Page 21: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/21.jpg)
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console– docgenerator– groovydoc– groovysh– ant– bsf
– jsr-223– jmx– sql– swing– servlet– templates
– test– testng– json– xml
17
![Page 22: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/22.jpg)
« Let’s go shopping »
![Page 23: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/23.jpg)
Extension modules
• Create your own extension module– contribute instance methods
package foo
class StringExtension { static introduces(String self, String name) { "Hi ${name), I’m ${self}" }}
// usage: "Guillaume".introduces("Cédric")
19
![Page 24: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/24.jpg)
Extension modules
• Create your own extension module– contribute instance methods
package foo
class StringExtension { static introduces(String self, String name) { "Hi ${name), I’m ${self}" }}
// usage: "Guillaume".introduces("Cédric")
Same structure as categories
19
![Page 25: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/25.jpg)
Extension modules
• Create your own extension module– contribute static methods
20
package foo
class StaticStringExtension { static hi(String self) { "Hi!" }}// usage: String.hi()
![Page 26: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/26.jpg)
Extension module descriptor
• META-INF/– services/
• org.codehaus.groovy.runtime.ExtensionModule
moduleName = stringExtensionsmoduleVersion = 1.0// comma separated list of FQN class namesextensionClasses = foo.StringExtension// comma separated list of FQN class namesstaticExtensionClasses = foo.StaticStringExtension
21
![Page 27: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/27.jpg)
Java 7 theme
« Project Coin » syntaxInvoke Dynamic support
![Page 28: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/28.jpg)
Binary literals
• In addition to decimal, octal and hexa• A new binary representation:
int x = 0b10101111assert x == 175 byte aByte = 0b00100001assert aByte == 33 int anInt = 0b1010000101000101assert anInt == 41285
23
![Page 29: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/29.jpg)
![Page 30: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/30.jpg)
Underscores in literals
• Use underscores in number literals
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
25
![Page 31: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/31.jpg)
Multi-catch exception blocks
• A single catch block to catch several exceptions at once, rather than duplicating blocks
try { /* ... */} catch(IOException | NullPointerException e) { /* un seul bloc */}
26
![Page 32: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/32.jpg)
Woot!
![Page 33: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/33.jpg)
JDK 7 Invoke Dynamic support
• A « flag » to compile with « indy »– we might propose a backport for JDK < 7
• Avantages– more runtime performance
•well... in theory...– In the long term, we might replace
•« call site caching » ➔ MethodHandles•« metaclass registry » ➔ ClassValues
– and the JIT « inlines » code more easily
28
![Page 34: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/34.jpg)
A « static » theme
Static type checkingStatic compilation
![Page 35: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/35.jpg)
Static type checking
• Goal: make the compiler grumpy!
– throw errors at compile-time• rather than at runtime
30
![Page 36: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/36.jpg)
We don’t need dynamic features
all the time!
![Page 37: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/37.jpg)
We don’t need dynamic features
all the time!
Nah !
![Page 38: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/38.jpg)
Static type checking
• A « grumpy » compiler should...
– say when there’s a typoin a method or variable name
– complain when a non-existent method is called
– or on bad assignments or use a bad return type
32
![Page 39: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/39.jpg)
Static type checking
• The compiler should infer types...
– less explicit types and casts
– fine grained type inference•« flow typing »•« lowest upper bound »
33
![Page 40: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/40.jpg)
Static type checking
• But the compiler should understand extension methods
– allows a good level of dynamism, despite the additional restrictions
34
![Page 41: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/41.jpg)
Typos
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
35
![Page 42: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/42.jpg)
Typos
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
Compilation error
35
![Page 43: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/43.jpg)
Typos
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
Compilation error
Compilation error
35
![Page 44: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/44.jpg)
Typos
import groovy.transform.TypeChecked void method() {} @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood() def name = "Guillaume" // variable naamme is undeclared println naamme}
Compilation error
Compilation error
Annotation at the method or class level
35
![Page 45: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/45.jpg)
Wrong variable assignments
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
36
![Page 46: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/46.jpg)
Wrong variable assignments
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
Compilation error
36
![Page 47: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/47.jpg)
Wrong variable assignments
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
Compilation error
Compilation error
36
![Page 48: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/48.jpg)
Wrong variable assignments
// cannot assign value of type... to variable...int x = new Object()Set set = new Object() String[] strings = ['a','b','c']int str = strings[0] // cannot find matching method plus()int i = 0i += '1'
Compilation error
Compilation error
Compilation error
36
![Page 49: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/49.jpg)
Wrong return type
// 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}
37
![Page 50: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/50.jpg)
Wrong return type
// 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}
Compilation error
37
![Page 51: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/51.jpg)
Wrong return type
// 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}
Compilation error
In the end, call StringBuilder’s toString()
37
![Page 52: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/52.jpg)
Type inference
@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 }}
38
![Page 53: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/53.jpg)
Type inference
@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 }}
Variable optionally typed
38
![Page 54: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/54.jpg)
Type inference
@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 }}
Variable optionally typed
Type String infered
38
![Page 55: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/55.jpg)
Type inference
@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 }}
Variable optionally typed
trim() method added dynamically by Groovy
Type String infered
38
![Page 56: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/56.jpg)
Type inference
@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 }}
Variable optionally typed
Array element type inferred
trim() method added dynamically by Groovy
Type String infered
38
![Page 57: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/57.jpg)
Mix dynamic & statically checked code
@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()}
39
![Page 58: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/58.jpg)
Mix dynamic & statically checked code
@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()}
Statically checked
39
![Page 59: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/59.jpg)
Mix dynamic & statically checked code
@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()}
Statically checked
Dynamic
39
![Page 60: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/60.jpg)
Instanceof checks
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }}
40
![Page 61: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/61.jpg)
Instanceof checks
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }}
No need for casts
40
![Page 62: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/62.jpg)
Instanceof checks
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }}
No need for casts
No need for casts
40
![Page 63: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/63.jpg)
Instanceof checks
@TypeChecked void test(Object val) {
if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() }}
No need for casts
No need for castsUnderstand GDK’s method:
String#multiply(int)
40
![Page 64: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/64.jpg)
Lowest Upper Bound
• The smallest common « super » type– might be virtual (« non-denotable »)
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
41
![Page 65: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/65.jpg)
Lowest Upper Bound
• The smallest common « super » type– might be virtual (« non-denotable »)
@TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14]}
Infered type:List<T extends Number & Comparable & Serializable>
41
![Page 66: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/66.jpg)
Flow typing
• Static type checking « follows » the type of values assigned into variables
@TypeChecked test() { def var = 123 // int infered int x = var // var is an int var = "123" // assign a String into var
x = var.toInteger() // no cast needed
var = 123 x = var.toUpperCase() // error, var is an int !}
42
![Page 67: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/67.jpg)
Not really clean, your code!
![Page 68: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/68.jpg)
Not really clean, your code!
Grmmpf...no!
![Page 69: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/69.jpg)
Static type checking and dynamic code
•Type checking happens at compile-time– @TypeChecked doesn’t change behavior!
• do not confound with static compilation
• Most dynamic features can’t be checked– metaclass changes, categories...– dynamic variables from the « script binding »
• But compile-time metaprogramming OK– if enough type information is available
44
![Page 70: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/70.jpg)
But if it ain’t dynamic, can we compile
it statically?
![Page 71: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/71.jpg)
But if it ain’t dynamic, can we compile
it statically?
But of course!!!
![Page 72: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/72.jpg)
Static compilation
• Given the code is statically type checked, lots of type information was infered...so we can as well compile statically !
– ie. generate the same bytecode as javac
• Also interesting when stuck on JDK < 7to gain performance improvements
46
![Page 73: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/73.jpg)
Avantages of static compilation
• We gain:– type safety
• thanks to static type checking –the compiler builds upon it
– better performance• close to Java’s performance
– code immune to « monkey patching »•dynamic metaprogramming can interfere with your framework’s code
– smaller generated bytecode
47
![Page 74: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/74.jpg)
I canz do what I want wiz your code
![Page 75: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/75.jpg)
I canz do what I want wiz your code
Niark !
![Page 76: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/76.jpg)
Drawbacks for static compilation
• We lose...
– Some dynamic features• metaclass changes, categories
– Method « dynamic dispatch » can differ• but thanks to type inference, it’s as close as «classical» Groovy as possible
49
![Page 77: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/77.jpg)
Mix statically compiled code with dynamic
@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()}
50
![Page 78: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/78.jpg)
Mix statically compiled code with dynamic
@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()}
Statically compiled
50
![Page 79: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/79.jpg)
Mix statically compiled code with dynamic
@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()}
Statically compiled
Dynamic
50
![Page 80: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/80.jpg)
Mix statically compiled code with dynamic
@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()}
Statically compiled
Dynamic
Call a method with
dynamic content
50
![Page 81: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/81.jpg)
Mix statically compiled code with dynamic
@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()}
Statically compiled
Dynamic
Call a method with
dynamic content
Method signatures are a contract!
50
![Page 82: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/82.jpg)
What about performance?
• Comparisons between:
– Java
– Groovy•with static compilation (Groovy 2.0)•with primitive type optimization (Groovy 1.8)•no optimization (Groovy 1.7)
51
![Page 83: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/83.jpg)
What about performance?
Fibonacci Pi (π) quadrature
Binarytrees
Java
Staticcompilation
Primitive optimizations
No prim.optimizations
191 ms 97 ms 3.6 s
197 ms 101 ms 4.3 s
360 ms 111 ms 23.7 s
2590 ms 3220 ms 50.0 s1.7
1.8
2.x
52
![Page 84: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/84.jpg)
...and now, ontoGroovy 2.1
Complete Invoke Dynamic supportMeta-annotationsAdvanced compiler configurationType checker extensions
![Page 85: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/85.jpg)
Invoke Dynamic
Complete support of Invoke Dynamic
![Page 86: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/86.jpg)
Meta-annotations
One annotationto rule them all!
![Page 87: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/87.jpg)
Meta-annotations
• Create meta-annotations which combine and/or parameterize other annotations
• And which work with AST transformations
56
![Page 88: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/88.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
57
![Page 89: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/89.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
Collected annotations
57
![Page 90: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/90.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
Collected annotations
The collector
57
![Page 91: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/91.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
Collected annotations
The collector
Your own annotation
alias
57
![Page 92: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/92.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
@MyAliasclass Person { String name int age}
Collected annotations
The collector
Your own annotation
alias
57
![Page 93: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/93.jpg)
Meta-annotations
@Immutable@ToString(excludes = ["age"])@AnnotationCollector@interface MyAlias {}
@MyAliasclass Person { String name int age}
Collected annotations
The collector
Your own annotation
aliasUse your meta-
annotation
57
![Page 94: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/94.jpg)
@DelegatesTo annotation
Richer tooling supportfor Domain-Specific Languages
![Page 95: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/95.jpg)
@DelegatesTo annotation
• Static type checking works fine with a certain range of DSLs– « command chains », extension methods...
• But less for DSLs using closure delegation– often used by DSLs like in Gradle
task copyTask(type: Copy) { from 'src/main/webapp' into 'build/explodedWar'}
59
![Page 96: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/96.jpg)
@DelegatesTo annotation
exec(spec) { foo()}
60
![Page 97: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/97.jpg)
@DelegatesTo annotationclass ExecSpec { void foo()}
exec(spec) { foo()}
60
![Page 98: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/98.jpg)
@DelegatesTo annotationclass ExecSpec { void foo()}
void exec(ExecSpec sp, Closure c) { c.delegate = sp c()}
exec(spec) { foo()}
60
![Page 99: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/99.jpg)
@DelegatesTo annotationclass ExecSpec { void foo()}
void exec(ExecSpec sp, Closure c) { c.delegate = sp c()}
exec(spec) { foo()}
The static type checker doesn’t know about method foo()
60
![Page 100: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/100.jpg)
@DelegatesTo annotationclass ExecSpec { void foo()}
void exec(ExecSpec sp, Closure c) { c.delegate = sp c()}
exec(spec) { foo()}
Annotate with @DelegatesTo(ExecSpec)
The static type checker doesn’t know about method foo()
60
![Page 101: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/101.jpg)
@DelegatesTo annotation
• With another delegation strategy
void exec(ExecSpec sp, Closure c) { c.delegate = sp c.resolveStrategy = DELEGATE_FIRST c()}
61
![Page 102: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/102.jpg)
@DelegatesTo annotation
• With another delegation strategy
void exec(ExecSpec sp, Closure c) { c.delegate = sp c.resolveStrategy = DELEGATE_FIRST c()}
Annotate with@DelegatesTo(value = ExecSpec,
strategy = DELEGATE_FIRST)
61
![Page 103: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/103.jpg)
@DelegatesTo annotation
• Very interesting for DSLs using closure’s delegation strategy
• Excellent for...– documenting your APIs– the integration within the IDE
• code completion, code navigation
– works well with static type checking and static compilation
62
![Page 104: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/104.jpg)
Extend the static type checker
To go even further than Java itself !
![Page 105: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/105.jpg)
Extend the static type checker
• Extend the type checker to make it smarter!– even smarter than Java’s! :-)
• By creating your own extension
@TypeChecked(extensions = 'MyExtension.groovy')void exec() { // code to be further checked...}
64
![Page 106: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/106.jpg)
Extend the static type checker
• Extend the type checker to make it smarter!– even smarter than Java’s! :-)
• By creating your own extension
@TypeChecked(extensions = 'MyExtension.groovy')void exec() { // code to be further checked...}
We could use a meta-annotation
64
![Page 107: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/107.jpg)
Extend the static type checker
• Help the static type checker when...
– impossible to infer types– no matching method found– no matching attribute found– on wrong variable assignment– ...
65
![Page 108: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/108.jpg)
Extend the static type checker
• Your extension has access to an event-oriented API
66
• onMethodSelection
• afterMethodCall• beforeMethodCall
• afterVisitMethod• beforeVisitMethod
• methodNotFound• unresolvedVariable• unresolvedProperty• unresolvedAttribute
• incompatibleAssignment
![Page 109: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/109.jpg)
Extend the static type checker
onMethodSelection { expr, method -‐> ... }afterMethodCall { mc -‐> ... }unresolvedVariable { var -‐> ... }methodNotFound { receiver, name, argList, argTypes, call -‐> ... }incompatibleAssignment { lhsType, rhsType, expr -‐> ... }
67
![Page 110: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/110.jpg)
Extend the static type checker
onMethodSelection { expr, method -‐> ... }afterMethodCall { mc -‐> ... }unresolvedVariable { var -‐> ... }methodNotFound { receiver, name, argList, argTypes, call -‐> ... }incompatibleAssignment { lhsType, rhsType, expr -‐> ... }
MyExtension.groovy
67
![Page 111: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/111.jpg)
Extend the static type checker
onMethodSelection { expr, method -‐> ... }afterMethodCall { mc -‐> ... }unresolvedVariable { var -‐> ... }methodNotFound { receiver, name, argList, argTypes, call -‐> ... }incompatibleAssignment { lhsType, rhsType, expr -‐> ... }
MyExtension.groovy
Learn your Groovy AST!
67
![Page 112: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/112.jpg)
Extend the static type checker
onMethodSelection { expr, method -‐> ... }afterMethodCall { mc -‐> ... }unresolvedVariable { var -‐> ... }methodNotFound { receiver, name, argList, argTypes, call -‐> ... }incompatibleAssignment { lhsType, rhsType, expr -‐> ... }
MyExtension.groovy
Learn your Groovy AST!
No need to be pre-compiled
67
![Page 113: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/113.jpg)
Extend the static type checker
• A few examples
– check that a string is a valid SQL query
– check the arguments and types of sprintf() method calls so they match the pattern
68
![Page 114: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/114.jpg)
Compiler configuration
Custom base script classConfiguration script
Configuration DSL
![Page 115: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/115.jpg)
Compiler customization
• Groovy 1.8 introduced « customizers »– add imports transparently– apply AST transformations by default– filter / secure scripts
• With the « static type checker » and « static compilation », we were asked if we could apply them by default
70
![Page 116: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/116.jpg)
Compiler customization
• New options
– --basescript to define a base script class for your scripts
– --configscript to indicate a script to configure the CompilerConfiguration object
71
![Page 117: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/117.jpg)
Compiler customization
• Add the @ToString AST transformation
import groovy.transform.ToStringimport org.codehaus.groovy.control.customizers .ASTTransformationCustomizer
configuration.addCompilationCustomizer( new ASTTransformationCustomizer(ToString))
72
![Page 118: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/118.jpg)
Compiler customization
• Add the @ToString AST transformation
import groovy.transform.ToStringimport org.codehaus.groovy.control.customizers .ASTTransformationCustomizer
configuration.addCompilationCustomizer( new ASTTransformationCustomizer(ToString))
CompilerConfiguration instance,injected by default
72
![Page 119: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/119.jpg)
Compiler customization
• A small DSL to configure the customization
configuration.customizers { // apply to MyBean.groovy source(basename: 'MyBean') { ast(ToString) }}
73
![Page 120: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/120.jpg)
Compiler customization
• A small DSL to configure the customization
configuration.customizers { // apply to MyBean.groovy source(basename: 'MyBean') { ast(ToString) }}
configuration.customizers { // apply to *.gbean files source(extension: '.gbean') { ast(ToString) }}
73
![Page 121: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/121.jpg)
Compiler customization
• A small DSL to configure the customization
configuration.customizers { // apply to MyBean.groovy source(basename: 'MyBean') { ast(ToString) }}
configuration.customizers { // apply to *.gbean files source(extension: '.gbean') { ast(ToString) }}
configuration.customizers { // custom filter logic source(unitValidator: { unit -‐> ... }) { ast(ToString) imports { staticStar 'java.lang.Math' } }}
73
![Page 122: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/122.jpg)
To learn more...Groovy 2.0http://groovy.codehaus.org/Groovy+2.0+release+notes
Groovy 2.1http://groovy.codehaus.org/Groovy+2.1+release+notes
![Page 123: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/123.jpg)
And what’s next?Groovy 2.2, 2.3 & 3 !
New « MOP »New Grammar with Antlr v4Java 8 Lambdas support
![Page 124: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/124.jpg)
A few words about the roadmap
2014 2014 20132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
![Page 125: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/125.jpg)
A few words about the roadmap
2014 2014 20132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
![Page 126: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/126.jpg)
A few words about the roadmap
2014 2014 20132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
![Page 127: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/127.jpg)
Groovy 2.2
Implicit closure coercion@Memoized transformation
DelegatingScript base script class
![Page 128: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/128.jpg)
Implicit closure coercion
78
![Page 129: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/129.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
78
![Page 130: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/130.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
Given a predicate & a List method to filter according to that predicate...
78
![Page 131: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/131.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
Given a predicate & a List method to filter according to that predicate...
78
![Page 132: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/132.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
Given a predicate & a List method to filter according to that predicate...
Java 8 lambdas can be more concise than Groovy!
78
![Page 133: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/133.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
list.filter({ it.age > 18 } as Predicate)
Given a predicate & a List method to filter according to that predicate...
Java 8 lambdas can be more concise than Groovy!
78
![Page 134: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/134.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
list.filter { it.age > 18 }
Given a predicate & a List method to filter according to that predicate...
Java 8 lambdas can be more concise than Groovy!
78
![Page 135: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/135.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
list.filter { it.age > 18 }
Given a predicate & a List method to filter according to that predicate...
Java 8 lambdas can be more concise than Groovy!
When no ambiguity, make coercion implicit!
78
![Page 136: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/136.jpg)
Implicit closure coercion
interface Predicate<T> { boolean test(T t)}
List<T> filter(Predicate<T> p)
list.filter((it) -‐> it.age > 18)
list.filter { it.age > 18 }
Given a predicate & a List method to filter according to that predicate...
Java 8 lambdas can be more concise than Groovy!
When no ambiguity, make coercion implicit!
Go beyond Java, by making it work on abstract classes too
78
![Page 137: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/137.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
79
![Page 138: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/138.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
Handy for DSLs!
79
![Page 139: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/139.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
Handy for DSLs!
name = "Guillaume"sayHi()
79
![Page 140: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/140.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
class Person { String name
void sayHi() { println "Hi $name" }}
Handy for DSLs!
name = "Guillaume"sayHi()
79
![Page 141: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/141.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
class Person { String name
void sayHi() { println "Hi $name" }}
Handy for DSLs!
name = "Guillaume"sayHi()
Use Person’s name property
79
![Page 142: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/142.jpg)
DelegatingScript base script class
• Special base script class to delegate method calls and property accesses to a delegatee
class Person { String name
void sayHi() { println "Hi $name" }}
Handy for DSLs!
name = "Guillaume"sayHi()
Use Person’s name property
Call Person#sayHi()
79
![Page 143: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/143.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
80
![Page 144: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/144.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
Specify DelegatingScript base class
80
![Page 145: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/145.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
Specify DelegatingScript base class
Parse the script
80
![Page 146: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/146.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
80
![Page 147: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/147.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
Run the script
80
![Page 148: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/148.jpg)
DelegatingScript base script class
• Integration example:
def cc = new CompilerConfiguration()cc.scriptBaseClass = DelegatingScript.class.name
def sh = new GroovyShell(cc)def script = sh.parse(file)
def p = new Person()script.setDelegate(p)script.run()
assert p.name == "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
Run the script
Be Happy!80
![Page 149: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/149.jpg)
groovysh doc command
81
![Page 150: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/150.jpg)
groovysh doc command
Launches your browser with the JavaDoc and GDK doc of the class
81
![Page 151: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/151.jpg)
groovysh code completion
82
![Page 152: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/152.jpg)
groovysh code completion
Import completion
82
![Page 153: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/153.jpg)
groovysh code completion
Import completion
Method call completion
82
![Page 154: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/154.jpg)
@Memoized transformation
• Piggypack on Closure’s own memoization capabilities, but applied to methods
@Memoized int expensiveOp(int a, int b) { sleep 1000 return a + b}// one second to returnexpensiveOp(1, 2) // immediate result returnedexpensiveOp(1, 2)
83
![Page 155: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/155.jpg)
Miscelanous improvements
• Precompiled type checking extensions
• Further tweaks to Groovysh with code completion, better error reporting...
• Better syntax highlighting in Groovy Console
• Various dependency upgrades (Gradle, Ant)
@TypeChecked(extensions = 'fqn.MyExtension')
84
![Page 156: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/156.jpg)
Additional GDK methods...
• groupBy() on arrays
• combinations(Closure)
• collectMany() on Iterables
• JsonSlurper’s parse(File) and parse(URL)
assert [[2, 3], [4, 5, 6]] .combinations { x, y -‐> x*y } == [8, 12, 10, 15, 12, 18]
85
![Page 157: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/157.jpg)
Likely inGroovy 2.3
TraitsGroovyDoc rewrite
New documentation & website
![Page 158: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/158.jpg)
Trait implementation
87
![Page 159: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/159.jpg)
Trait implementation
trait FlyingAbility { String fly() { "I believe I can fly!" }}
87
![Page 160: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/160.jpg)
Trait implementation
trait FlyingAbility { String fly() { "I believe I can fly!" }}
A trait keyword applying the @Trait transformation
87
![Page 161: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/161.jpg)
Trait implementation
trait FlyingAbility { String fly() { "I believe I can fly!" }}
A trait keyword applying the @Trait transformation
class Car implements FlyingAbility {}
87
![Page 162: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/162.jpg)
Trait implementation
trait FlyingAbility { String fly() { "I believe I can fly!" }}
A trait keyword applying the @Trait transformation
class Car implements FlyingAbility {}
A class «implements» the trait
87
![Page 163: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/163.jpg)
Trait implementation
trait FlyingAbility { String fly() { "I believe I can fly!" }}
A trait keyword applying the @Trait transformation
class Car implements FlyingAbility {}
A class «implements» the trait
def c = new Car()assert c.fly() == "I believe I can fly!"
87
![Page 164: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/164.jpg)
GroovyDoc rewrite
88
![Page 165: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/165.jpg)
GroovyDoc rewrite
GroovyDoc != Sexy Doc
88
![Page 166: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/166.jpg)
New documentation and website
• New reference documentation and guides using AsciiDoctor
• New website with a refreshed skin and the new content
89
![Page 167: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/167.jpg)
Groovy 3
New MOPNew Antlr v4 grammarJDK 8 lambda support
![Page 168: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/168.jpg)
MOP
2
![Page 169: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/169.jpg)
Antlr 4grammar
![Page 170: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/170.jpg)
λJDK
8
![Page 171: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/171.jpg)
![Page 172: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/172.jpg)
Summary
• A very rich and blossoming ecosystem•Groovy 2.0
– more modular– a static theme
• static type checking• static compilation
– JDK 7 theme• Invoke Dynamic support• Project Coin syntax enhancements
95
![Page 173: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/173.jpg)
Summary
•Groovy 2.1– Invoke Dynamic support completed– @DelegatesTo annotation– type checker extensions for DSLs– meta-annotations
96
![Page 174: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/174.jpg)
Summary
• Groovy 2.2 – implicit closure coercion– @Memoized transformation– DelegatingScript for script DSLs– groovysh improvements
97
![Page 175: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/175.jpg)
Summary
• Groovy 2.3– traits– new GroovyDoc– new documentation– new website
98
![Page 176: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/176.jpg)
Summary
• Groovy 3– a new MOP (Meta-Object Protocol)– a new grammar with Antlr v4– the support of JDK 8 and lambdas
99
![Page 177: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/177.jpg)
Questions & Answers
![Page 178: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/178.jpg)
Thank you! @glaforge
http://glaforge.appspot.com
http://gplus.to/glaforge
![Page 179: Lift off with Groovy 2 at JavaOne 2013](https://reader034.vdocuments.us/reader034/viewer/2022052410/55587516d8b42a8d018b5280/html5/thumbnails/179.jpg)
Image credits• lift-off: http://www.wpclipart.com/space/ships/space_shuttle/Space_Shuttle_liftoff.png
• anniversary: http://www.empowernetwork.com/fam/files/2013/03/happy_birthday_cake_with_candles-1920x1200.jpg
• cerisier: http://wallpaperswide.com/cherry_blossom_3-wallpapers.html
• NKOTB: http://images1.fanpop.com/images/photos/2300000/nkotb-new-kids-on-the-block-2314664-1280-960.jpg
• lunar module: http://www.clavius.org/img/lm-diag.gif
• tomates: http://www.infoescola.com/wp-content/uploads/2011/01/tomate.jpg
• patates: http://toooof.free.fr/blogs/captainslip/screenshots/pommes_de_terre.jpg
• coins: http://www.coins-jewelry.com/c22.png
• more coins: http://diamond-center.co.il/upload/articles/gold-coins1.jpg
• binary: http://okletsgo.co.uk/img/binary.jpg
• grumpy: https://si0.twimg.com/profile_images/3115998027/b47c180a703a5ffa7d1437a66f545dc0.jpeg
• singe: http://static.ddmcdn.com/gif/how-to-draw-animals-31.jpg
• warning: http://th07.deviantart.net/fs71/PRE/i/2012/261/8/6/warning_gangnam_style_zone_by_untoucheddesigns-d5f6bal.png
• coyote: http://nittygriddy.com/wp-content/uploads/2011/01/Wiley-Coyote-Help.jpg
• ring: http://img.banggood.com/images/upload/2012/limin/SKU028431_11.JPG
• magnifying glass: http://www.renders-graphiques.fr/image/upload/normal/loupe.png
• work in progress: http://www.sbscompany.org/multimedia/immagini/work-in-progress.png
• tab key: http://www.meganga.com/wp-content/uploads/2012/03/Tab-Key-Word-Tutorials.jpg
• chronomètre: http://www.moineau-instruments.com/59-thickbox/chronometre-mecanique-1-10-t15-mn-2-fonctions.jpg
• that’s all folks: http://4.bp.blogspot.com/-wJxosualm48/T4M_spcUUjI/AAAAAAAAB8E/njfLjNZQdsc/s1600/thats-all-folks.jpg
• MOP: http://imagethumbnails.milo.com/024/913/894/trimmed/24913521_25989894_trimmed.jpg
• grammar: http://edudemic.com/wp-content/uploads/2012/11/connected-learner-grammar.jpg
102