Groovy Update - Guillaume Laforge - Greach 2011

172
Guillaume Laforge Groovy Project Manager SpringSource, a division of VMware Twitter: @glaforge Blog: http://glaforge.appspot.com Google+: http://gplus.to/glaforge Whatʼs new in Groovy 1.8 and beyond?

description

Overview of the features of Groovy 1.8 and what is coming in the next major version.

Transcript of Groovy Update - Guillaume Laforge - Greach 2011

Page 1: Groovy Update - Guillaume Laforge - Greach 2011

Guillaume LaforgeGroovy Project ManagerSpringSource, a division of VMware

Twitter: @glaforgeBlog: http://glaforge.appspot.comGoogle+: http://gplus.to/glaforge

Whatʼs new in Groovy 1.8 and beyond?

Page 2: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Guillaume Laforge

• Groovy Project Manager at VMware• Initiator of the Grails framework• Creator of the Gaelyk toolkit

• Co-author of Groovy in Action• Speaking worldwide w/ a French accent

• Follow me on...• My blog: http://glaforge.appspot.com• Twitter: @glaforge• Google+: http://gplus.to/glaforge

2

Page 3: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Guillaume Laforge

• Groovy Project Manager at VMware• Initiator of the Grails framework• Creator of the Gaelyk toolkit

• Co-author of Groovy in Action• Speaking worldwide w/ a French accent

• Follow me on...• My blog: http://glaforge.appspot.com• Twitter: @glaforge• Google+: http://gplus.to/glaforge

2

Page 4: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

3

Page 5: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

1853

Page 6: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

185k3

Page 7: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

185kFIRST MONTH AFTER RELEASE

3

Page 8: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

k3

Page 9: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

k177SECOND MONTH AFTER RELEASE

3

Page 10: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

k3

Page 11: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.7

k362USERS?

3

Page 12: Groovy Update - Guillaume Laforge - Greach 2011

TIP OF THEICEBERG?

Page 13: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

1/2Million U

sers

Guesstimate

5

Page 14: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Agenda

6

Page 15: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Agenda

• Whatʼs new in Groovy 1.8?– Nicer DSLs with command chains expressions– Runtime performance improvements– GPars bundled for taming your multicores– Closure enhancements– Builtin JSON support– New AST transformations

6

Page 16: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Agenda

• Whatʼs new in Groovy 1.8?– Nicer DSLs with command chains expressions– Runtime performance improvements– GPars bundled for taming your multicores– Closure enhancements– Builtin JSON support– New AST transformations

• Whatʼs cooking for Groovy 1.9?– Continued runtime performance improvements– Alignments with JDK 7

• Project Coin (small language changes)• Static type checking• InvokeDynamic

6

Page 17: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

7

Page 18: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

• A grammar improvement allowing you todrop dots & parens when chaining method calls– an extended version of top-level statements like println

7

Page 19: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

• A grammar improvement allowing you todrop dots & parens when chaining method calls– an extended version of top-level statements like println

7

Page 20: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

• A grammar improvement allowing you todrop 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)

7

Page 21: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

• A grammar improvement allowing you todrop 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)

7

Page 22: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

• A grammar improvement allowing you todrop 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)

• Letʼs have a look at some examples

7

Page 23: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

 turn left  then right 

8

Page 24: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

 turn left  then right 

Alternation of method names

8

Page 25: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

 turn left  then right 

Alternation of method names

and parameters(even named ones)

8

Page 26: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

 turn left  then right 

8

Page 27: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

 turn left  then right      (    ).    (     )

Equivalent to:

8

Page 28: Groovy Update - Guillaume Laforge - Greach 2011

Look Ma!No parens, no dots!

Page 29: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills, of: chloroquinine, after: 6.hours

Before... we used to do...

10

Page 30: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills, of: chloroquinine, after: 6.hours

Before... we used to do...

Normal argument

10

Page 31: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills, of: chloroquinine, after: 6.hours

Before... we used to do...

Normal argument Named arguments

10

Page 32: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills, of: chloroquinine, after: 6.hours

Before... we used to do...

Normal argument Named arguments

Woud call:

def take(Map m, Quantity q)

10

Page 33: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills  of  chloroquinine  after  6.hours

Now, even less punctuation!

11

Page 34: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills  of  chloroquinine  after  6.hours

Now, even less punctuation!

    (       ).   (             ).      (       )

11

Page 35: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// environment initializationInteger.metaClass.getPills { ‐> delegate }Integer.metaClass.getHours { ‐> delegate } // variable injectiondef chloroquinine = /*...*/ // implementing the DSL logicdef take(n) {    [of: { drug ‐>        [after: { time ‐> /*...*/ }]    }]}

// ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐take 2.pills of chloroquinine after 6.hours

{ }12

Page 36: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills  of  chloroquinine  after  6.hours

13

Page 37: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2.pills  of  chloroquinine  after  6.hours

... some dots remain ...

13

Page 38: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2  pills of  chloroquinine  after  6 hours

Yes, we can... get rid of them :-)

14

Page 39: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

take 2  pills of  chloroquinine  after  6 hours

Yes, we can... get rid of them :-)

    ( ).     (  ).              (     ). (     )

14

Page 40: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// variable injectiondef (of, after, hours) = /*...*/ // implementing the DSL logicdef take(n) {    [pills: { of ‐>        [chloroquinine: { after ‐>            ['6': { time ‐> }]        }]    }]}

// ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐take 2 pills of chloroquinine after 6 hours

{ }15

Page 41: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

16

Page 42: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// methods with multiple arguments (commas)

16

Page 43: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// methods with multiple arguments (commas)take coffee  with sugar, milk  and liquor

16

Page 44: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// methods with multiple arguments (commas)take coffee  with sugar, milk  and liquor

// leverage named‐args as punctuation

16

Page 45: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// methods with multiple arguments (commas)take coffee  with sugar, milk  and liquor

// leverage named‐args as punctuationcheck that: margarita  tastes good

16

Page 46: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

16

Page 47: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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 {}

16

Page 48: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

16

Page 49: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

16

Page 50: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

16

Page 51: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

16

Page 52: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

    (      ).    (           ).   (      )

16

Page 53: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

    (      ).    (           ).   (      )

     (               ).      (    )

16

Page 54: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

    (      ).    (           ).   (      )

     (               ).      (    )

     (  ).    (  ).    (  )

16

Page 55: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

    (      ).    (           ).   (      )

     (               ).      (    )

     (  ).    (  ).    (  )

      (   ).        .    (     )

16

Page 56: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Command chains expressions

// 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

    (      ).    (           ).   (      )

     (               ).      (    )

     (  ).    (  ).    (  )

      (   ).        .    (     )

    ( ).

16

Page 57: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Runtime performance improvements

• Significant runtime improvements for primitive type operations– classical Fibonacci example x13 faster!– almost as fast as Java

• Some direct method calls on this

17

Page 58: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

GPars bundled

• GPars is bundled in the Groovy distribution

• GPars covers a wide range of parallel and concurrent paradigms– actors, fork/join, map/filter/reduce, dataflow, agents, STM– parallel arrays, executors, and more...

18

Page 59: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure enhancements

• Closure annotation parameters

• Some more functional flavor– composition– trampoline– memoization

• Currying improvements

19

Page 60: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure annotation parameters

20

@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 61: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure annotation parameters

20

@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 62: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure composition

21

def plus2  = { it + 2 }def times3 = { it * 3 }  def times3plus2 = plus2 << times3assert times3plus2(3) == 11assert times3plus2(4) == plus2(times3(4))  def plus2times3 = times3 << plus2assert plus2times3(3) == 15assert plus2times3(5) == times3(plus2(5))  // reverse compositionassert times3plus2(3) == (times3 >> plus2)(3)

{

{

{

Page 64: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure trampoline

22

def factorial

factorial = { int n, BigInteger accu = 1G ‐>        if (n < 2) return accu         factorial.trampoline(n ‐ 1, n * accu)}.trampoline() assert factorial(1)    == 1assert factorial(3)    == 1 * 2 * 3assert factorial(1000) == 402387260...

Page 65: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

Page 66: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

def plus = { a, b ‐> sleep 1000; a + b }.memoize()

Page 67: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

def plus = { a, b ‐> sleep 1000; a + b }.memoize()

assert plus(1, 2) == 3 // after 1000ms

Page 68: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

def plus = { a, b ‐> sleep 1000; a + b }.memoize()

assert plus(1, 2) == 3 // after 1000msassert plus(1, 2) == 3 // return immediately

Page 69: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 70: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 71: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 72: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 73: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 74: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 75: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 76: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 77: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 78: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Closure memoization

23

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 79: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Currying improvements

24

Page 80: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Currying improvements

24

// right curryingdef divide = { a, b ‐> a / b }def halver = divide.rcurry(2)assert halver(8) == 4   

Page 81: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Currying improvements

24

// right curryingdef divide = { a, b ‐> a / b }def halver = divide.rcurry(2)assert halver(8) == 4   // currying n‐th parameterdef joinWithSeparator =     { one, sep, two ‐> one + sep + two }def joinWithComma =     joinWithSeparator.ncurry(1, ', ')assert joinWithComma('a', 'b') == 'a, b'

Page 82: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Builtin JSON support

• Consuming

• Producing

• Pretty-printing

25

Page 83: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Builtin JSON support

26

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 84: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Builtin JSON support

27

import groovy.json.*  def json = new JsonBuilder()  json.person {        name "Guillaume"    age 33        pets "Hector", "Felix"} println json.toString()

Page 85: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Builtin JSON support

28

import groovy.json.*  println JsonOutput.prettyPrint(    '''{"person":{"name":"Guillaume","age":33,''' +     '''"pets":["Hector","Felix"]}}''') 

Page 86: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Builtin JSON support

28

import groovy.json.*  println JsonOutput.prettyPrint(    '''{"person":{"name":"Guillaume","age":33,''' +     '''"pets":["Hector","Felix"]}}''') 

{        "person": {                "name": "Guillaume",                "age": 33,                "pets": [                        "Hector",                        "Felix"                ]        }}

Page 87: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New AST transformations

• @Log

• @Field

• @AutoClone• @AutoExternalizable

• Controlling the execution of your code– @ThreadInterrupt, – @TimedInterrupt, – @ConditionalInterrupt

• @Canonical– @ToString, – @EqualsAndHashCode, – @TupleConstructor

• @InheritConstructor

• @WithReadLock• @WithWriteLock

• @ListenerList

29

Page 88: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@Log

• Four different loggers can be injected– @Log, @Commons, @Log4j, @Slf4j

• Possible to implement your own strategy

30

import groovy.util.logging.*  @Logclass Car {        Car() {                log.info 'Car constructed'        }}  def c = new Car()

Page 89: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@Log

• Four different loggers can be injected– @Log, @Commons, @Log4j, @Slf4j

• Possible to implement your own strategy

30

import groovy.util.logging.*  @Logclass Car {        Car() {                log.info 'Car constructed'        }}  def c = new Car()

Guardedw/ an if

Page 90: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@Field

• Surprising scoping rules in scripts– variables are local to the run() method– variables arenʼt visible in methods

• although visually the variable is in a surrounding scope

• @Field creates a field in the script class

31

@Field List awe = [1, 2, 3]def awesum() { awe.sum() }assert awesum() == 6

Page 91: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

• Your application may run userʼs code– what if the code runs in infinite loops or for too long?– what if the code consumes too many resources?

32

Controlling code execution

Page 92: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

• Your application may run userʼs code– what if the code runs in infinite loops or for too long?– what if the code consumes too many resources?

• 3 new transforms at your rescue– @ThreadInterrupt: adds Thread#isInterrupted checks so your

executing thread stops when interrupted– @TimedInterrupt: adds checks in method and closure bodies to

verify itʼs run longer than expected– @ConditionalInterrupt: adds checks with your own conditional

logic to break out from the user code

32

Controlling code execution

Page 93: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

• Your application may run userʼs code– what if the code runs in infinite loops or for too long?– what if the code consumes too many resources?

• 3 new transforms at your rescue– @ThreadInterrupt: adds Thread#isInterrupted checks so your

executing thread stops when interrupted– @TimedInterrupt: adds checks in method and closure bodies to

verify itʼs run longer than expected– @ConditionalInterrupt: adds checks with your own conditional

logic to break out from the user code

32

Controlling code execution

Page 94: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

• Your application may run userʼs code– what if the code runs in infinite loops or for too long?– what if the code consumes too many resources?

• 3 new transforms at your rescue– @ThreadInterrupt: adds Thread#isInterrupted checks so your

executing thread stops when interrupted– @TimedInterrupt: adds checks in method and closure bodies to

verify itʼs run longer than expected– @ConditionalInterrupt: adds checks with your own conditional

logic to break out from the user code

• Also see compilation customizers later on32

Controlling code execution

Page 95: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@ThreadInterrupt

33

@ThreadInterruptimport groovy.transform.ThreadInterrupt  while (true) {

    // eat lots of CPU}

33

Page 96: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@ThreadInterrupt

33

@ThreadInterruptimport groovy.transform.ThreadInterrupt  while (true) {

    // eat lots of CPU}

 

    if (Thread.currentThread.isInterrupted())        throw new InterruptedException(){ }

33

Page 97: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@ThreadInterrupt

• Two optional annotation parameters available– checkOnMethodStart (true by default)– applyToAllClasses (true by default)

33

@ThreadInterruptimport groovy.transform.ThreadInterrupt  while (true) {

    // eat lots of CPU}

 

    if (Thread.currentThread.isInterrupted())        throw new InterruptedException(){ }

33

Page 98: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@TimedInterrupt

• InterruptedException thrown when checks indicate code ran longer than desired

• Optional annotation parameters available– same as @ThreadInterrupt– value: for an amount of time duration– unit: for the time duration unit (TimeUnit.SECONDS)

34

@TimedInterrupt(10)import groovy.transform.TimedInterrupt  while (true) {    // eat lots of CPU}

Page 99: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@ConditionalInterrupt

• Specify your own condition to be inserted at the start of method and closure bodies– check for available resources, number of times run, etc.

• Leverages closure annotation parameters from Groovy 1.8

35

@ConditionalInterrupt({ counter++ > 2 })import groovy.transform.ConditionalInterruptimport groovy.transform.Field  @Field int counter = 0 

100.times {        println 'executing script method...'}

Page 100: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@ToString

• Provides a default toString() method to your types• Available annotation options

– includeNames, includeFields, includeSuper, excludes

36

import groovy.transform.ToString  @ToStringclass Person {        String name        int age}  println new Person(name: 'Pete', age: 15)// => Person(Pete, 15)

Page 101: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@EqualsAndHashCode

• Provides default implementations for equals() and hashCode() methods

37

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 102: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@TupleConstructor

• Provides a «classical» constructor with all properties• Several annotation parameter options available

38

import groovy.transform.TupleConstructor  @TupleConstructor class Person {        String name        int age}  def m = new Person('Marion', 3)       assert m.name == 'Marion'assert m.age  == 3

Page 103: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@Canonical

• One annotation to rule them all!– @Canonical mixes together

• @ToString• @EqualsAndHashCode• @TupleConstructor

• You can customize behavior by combining @Canonical and one of the other annotations

39

Page 104: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@InheritConstructor

• Classes like Exception are painful when extended, as all the base constructors should be replicated

40

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 105: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@InheritConstructor

• Classes like Exception are painful when extended, as all the base constructors should be replicated

40

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 106: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@WithReadLock, @WithWriteLock

41

import groovy.transform.*  class ResourceProvider {        private final Map<String, String> data = new HashMap<>()     @WithReadLock        String getResource(String key) {                return data.get(key)        }          @WithWriteLock        void refresh() {                //reload the resources into memory        }}

Page 107: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

@WithReadLock, @WithWriteLock

41

import groovy.transform.*  class ResourceProvider {        private final Map<String, String> data = new HashMap<>()     @WithReadLock        String getResource(String key) {                return data.get(key)        }          @WithWriteLock        void refresh() {                //reload the resources into memory        }}

{

{

Page 108: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Miscelanous

• Compilation customizers • Java 7 diamond operator• Slashy and dollar slashy strings• New GDK methods• (G)String to Enum coercion

42

Page 109: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Compilation customizers

• Ability to apply some customization to the Groovy compilation process

• Three available customizers– ImportCustomizer– ASTTransformationCustomizer– SecureASTCustomizer

• But you can implement your own

43

Page 110: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Imports customizer

44

def configuration = new CompilerConfiguration() def custo = new ImportCustomizer()custo.addStaticStar(Math.name)configuration.addCompilationCustomizers(custo)  def result = new GroovyShell(configuration)    .evaluate(" cos PI/3 ")

Page 111: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Applying an AST transformation

45

def configuration = new CompilerConfiguration()

configuration.addCompilationCustomizers(    new ASTTransformationCustomizer(Log))  new GroovyShell(configuration).evaluate("""    class Car {                Car() {                        log.info 'Car constructed'                }        }         log.info 'Constructing a car'        def c = new Car()""")

Page 112: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Secure AST customizer

• Letʼs setup our environment– some imports– an import customizer to import java.lang.Math.*– prepare a secure AST customizer

46

import org.codehaus.groovy.control.customizers.*import org.codehaus.groovy.control.*import static org.codehaus.groovy.syntax.Types.* def imports = new ImportCustomizer().addStaticStars('java.lang.Math')def secure = new SecureASTCustomizer()

Idea: Implement an «arithmetic shell»Being able control what a user script is allowed to do: only arithmetic expressions

Page 113: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Secure AST customizer

47

...secure.with {

// disallow closure creationclosuresAllowed = false // disallow method definitionsmethodDefinitionAllowed = false 

 // empty white list => forbid importsimportsWhitelist = [] staticImportsWhitelist = []// only allow the java.lang.Math.* static importstaticStarImportsWhitelist = ['java.lang.Math'

...

Page 114: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Secure AST customizer

48

...// language tokens allowedtokensWhitelist = [

PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, PLUS_PLUS, MINUS_MINUS, COMPARE_EQUAL, COMPARE_NOT_EQUAL, COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL, COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL

// types allowed to be used (including primitive types)constantTypesClassesWhiteList = [

Integer, Float, Long, Double, BigDecimal, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE

// classes who are allowed to be receivers of method callsreceiversClassesWhiteList = [ 

Math, Integer, Float, Double, Long, BigDecimal ]}...

Page 115: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Secure AST customizer

• Ready to evaluate our arithmetic expressions!

• But the following would have failed:

49

shell.evaluate 'System.exit(0)'

...def config = new CompilerConfiguration()config.addCompilationCustomizers(imports, secure)

def shell = new GroovyShell(config) shell.evaluate 'cos PI/3'

Page 116: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Slashy and dollar slashy strings

• Slashy strings are now multiline– particularly handy for multi-line regexs

• Dollar slashy string notation introduced– a multiline GString with different escaping rules

50

def (name, date) = ["Guillaume", "Oct, 26th"]def dollarSlashy = $/        Hello $name, today we're ${date}    $ dollar‐sign        $$ dollar‐sign        \ backslash        / slash       $/ slash/$ 

Page 117: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

Page 118: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// count

Page 119: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5

Page 120: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 

Page 121: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count by

Page 122: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }

Page 123: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' }

Page 124: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } 

Page 125: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closures

Page 126: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] 

Page 127: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'

Page 128: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1

Page 129: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1 

Page 130: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1 // map withDefault()

Page 131: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1 // map withDefault()def words = "one two two three three three".split()

Page 132: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1 // map withDefault()def words = "one two two three three three".split()def freq = [:].withDefault { k ‐> 0 }

Page 133: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

New GDK methods

51

// countassert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 // count byassert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }assert [(true):2, (false):4]     == 'Groovy'.toList().countBy{ it == 'o' } // min/max for maps with closuresdef map = [a: 1, bbb: 4, cc: 5, dddd: 2] assert map.max { it.key.size() }.key == 'dddd'assert map.min { it.value }.value == 1 // map withDefault()def words = "one two two three three three".split()def freq = [:].withDefault { k ‐> 0 }words.each { freq[it] += 1 }

Page 134: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

Page 135: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {    

Page 136: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue

Page 137: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue} 

Page 138: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  

Page 139: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with as

Page 140: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color 

Page 141: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  

Page 142: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  // implicit coercion

Page 143: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  // implicit coercionColor b = "blue" 

Page 144: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  // implicit coercionColor b = "blue"  

Page 145: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  // implicit coercionColor b = "blue"  // with GStrings too

Page 146: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

(G)String to Enum coercion

52

enum Color {        red, green, blue}  // coercion with asdef r = "red" as Color  // implicit coercionColor b = "blue"  // with GStrings toodef g = "${'green'}" as Color

Page 147: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Customizing the Groovysh prompt

53

Page 148: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Launching remote scripts

• With the Groovy command, you can launch remote scripts

• Be careful to what youʼre executing :-)

54

> groovy http://groovyconsole.appspot.com/raw/110001

Page 149: Groovy Update - Guillaume Laforge - Greach 2011

What’s cookingfor 1.9?

Page 150: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.9 roadmap

• Java 7 alignements: Project Coin– binary literals– underscore in literals– multicatch

• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking and compilation• Miscelanous

• What else? Your call!

56

Page 151: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy 1.9 roadmap

• Java 7 alignements: Project Coin– binary literals– underscore in literals– multicatch

• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking and compilation• Miscelanous

• What else? Your call!

56

Page 152: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Java 7 / JDK 7

• Project Coin and InvokeDynamic

57

Page 153: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Binary literals

• We had decimal, octal and hexadecimal notations for number literals

• We can now use binary representations too

58

int x = 0b10101111assert x == 175 byte aByte = 0b00100001assert aByte == 33 int anInt = 0b1010000101000101assert anInt == 41285

Page 154: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Underscore in literals

• Now we can also add underscores in number literals for more readability

59

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 155: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Multicatch

• One block for multiple exception caught– rather than duplicating the block

60

try {    /* ... */} catch(IOException | NullPointerException e) {    /* one block to treat 2 exceptions */}

Page 156: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

InvokeDynamic

• Groovy 1.9 will support JDK 7ʼs invokeDynamic– an «indy» branch started recently– compiler will have a flag for compiling against JDK 7

• Benefits– more runtime performance!– in the long run, will allow us to get rid of code!

• call site caching, thanks to MethodHandles• metaclass registry, thanks to ClassValues• will let the JIT inline calls more easily

61

Page 157: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Groovy Modularity

• Groovyʼs «all» JAR weighs in at 4MB

• Nobody needs everything– Template engine, Ant scripting, Swing UI building...

• Provide a smaller core– and several smaller JARs per feature

• Provide hooks for setting up EMCs / DGM methods, etc.

62

Page 158: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Static Type Checking

• Goal: make the Groovy compiler «grumpy»!– and throw compilation errors (not at runtime)

• Not everybody needs dynamic features all the time– think Java libraries scripting

• Grumpy should...– tell you about your method or variable typos– complain if you call methods that donʼt exist– shout on assignments of wrong types– infer the types of your variables– figure out GDK methods– etc...

63

Page 159: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

A typo in your variable or method names

64

import groovy.transform.StaticTypes void method() {} @TypeChecked test() {    // Cannot find matching method metthhoood()    metthhoood()     def name = "Guillaume"    // variable naamme is undeclared    println naamme}

Page 160: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

A typo in your variable or method names

64

import groovy.transform.StaticTypes void method() {} @TypeChecked test() {    // Cannot find matching method metthhoood()    metthhoood()     def name = "Guillaume"    // variable naamme is undeclared    println naamme}

Compilationerrors!

Page 161: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Complain on wrong assignments

65

// 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 162: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Complain on wrong assignments

65

// 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 163: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Complain on wrong return types

66

String method() { 'String' }// cannot assign value of type String...int x = method()

// checks if/else branch return valuesint method() {    if (true) { 'String' }    else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) {    def sb = new StringBuilder()    sb << "Hi" << name}

Page 164: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Complain on wrong return types

66

String method() { 'String' }// cannot assign value of type String...int x = method()

// checks if/else branch return valuesint method() {    if (true) { 'String' }    else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) {    def sb = new StringBuilder()    sb << "Hi" << name}

Compilationerrors!

Page 165: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Type inference

67

@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 166: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Staticly checked method & dynamic method

68

@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 167: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Bytecode viewer

• Groovy Consoleʼs bytecode viewerfrom the AST browser window– select class

generation phase– select a class node

69

Page 168: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Disable Global AST transformations

70

// witout a specific configuration, the AST builder worksdef shell = new GroovyShell()shell.evaluate(script) // passes

def config = new CompilerConfiguration()config.disabledGlobalASTTransformations =    ['org.codehaus.groovy.ast.builder.AstBuilderTransformation']def script = '''    import org.codehaus.groovy.ast.builder.AstBuilder    new AstBuilder().buildFromCode { "Hello" }''' // now with the configuration in place,// the AST builder transform is not appliedshell = new GroovyShell(config) // <‐‐ with the configurationshouldFail {    shell.evaluate(script) // fails}

Page 169: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Summary

71

ROCKS!

Page 171: Groovy Update - Guillaume Laforge - Greach 2011

Q&A — Got questions, Really?

Page 172: Groovy Update - Guillaume Laforge - Greach 2011

@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Image credits• Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg

• Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2

• Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg

• Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg

• Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/

• Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg

• Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg

• Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg

• Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg

• Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg

• Caution: http://www.jeunes-epinay-sur-seine.fr/wp-content/uploads/2010/11/caution-colocation.jpg

• Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg

• Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg

• Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg

• Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg

• WIP: http://www.connetport.com/wp-content/uploads/Work_in_progress.svg_.png

• Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg

74