SlideShare une entreprise Scribd logo
1  sur  172
Télécharger pour lire hors ligne
Whatʼs new in Groovy 1.8 and beyond?

Guillaume Laforge
Groovy Project Manager
SpringSource, a division of VMware

Twitter: @glaforge
Blog: http://glaforge.appspot.com
Google+: 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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   2
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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   2
Groovy 1.7




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




185
             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




185k
             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




185k    FIRST MONTH
        AFTER RELEASE

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




                                                            k
             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




177k    SECOND MONTH
        AFTER RELEASE

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




                                                            k
             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
Groovy 1.7




362k
 USERS?
             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   3
?
TIP OF
THE
ICEBERG
Guesstimate




   1/2
                                                        Users
   Million@glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   5
Agenda




         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   6
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




                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   6
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
                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   6
Command chains expressions




          @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions


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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions


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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions


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


• Less dots, less parens allow you to
  – write more readable business rules
  – in almost plain English sentences
    • (or any language, of course)




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions


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


• Less dots, less parens allow you to
  – write more readable business rules
  – in almost plain English sentences
    • (or any language, of course)




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions


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


• Less dots, less parens allow you to
  – write more readable business rules
  – in almost plain English sentences
    • (or any language, of course)


• Letʼs have a look at some examples


                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   7
Command chains expressions




        turn left  then right 




          @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   8
Command chains expressions
       Alternation of
       method names




        turn left  then right 




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   8
Command chains expressions
       Alternation of
       method names




        turn left  then right 


                                             and parameters
                                           (even named ones)




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   8
Command chains expressions




        turn left  then right 




          @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   8
Command chains expressions




       Equivalent to:


            (    ).    (     )
        turn left  then right 




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   8
LookM  a!
N op are ns,
no do ts!
Command chains expressions



    Before... we used to do...



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




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   10
Command chains expressions



    Before... we used to do...



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


    Normal argument




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   10
Command chains expressions



    Before... we used to do...



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


    Normal argument                            Named arguments




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   10
Command chains expressions



     Before... we used to do...



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


     Normal argument                            Named arguments


  Woud call:
  def take(Map m, Quantity q)


                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   10
Command chains expressions



     Now, even less punctuation!



 take 2.pills  of  chloroquinine  after  6.hours




                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   11
Command chains expressions



     Now, even less punctuation!



     (       ).   (             ).      (       )
 take 2.pills  of  chloroquinine  after  6.hours




                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   11
Command chains expressions
      // environment initialization
      Integer.metaClass.getPills { ‐> delegate }
      Integer.metaClass.getHours { ‐> delegate }
       
      // variable injection
      def chloroquinine = /*...*/
       




  {                                                                                  }
      // implementing the DSL logic
      def take(n) {
          [of: { drug ‐>
              [after: { time ‐> /*...*/ }]
          }]
      }

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


            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge       12
Command chains expressions




 take 2.pills  of  chloroquinine  after  6.hours




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   13
Command chains expressions




 take 2.pills  of  chloroquinine  after  6.hours


                      ... some dots remain ...




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   13
Command chains expressions



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



 take 2  pills of  chloroquinine  after  6 hours




               @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   14
Command chains expressions



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



     ( ).     (  ).              (     ). (     )
 take 2  pills of  chloroquinine  after  6 hours




               @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   14
Command chains expressions

      // variable injection
      def (of, after, hours) = /*...*/
       
      // implementing the DSL logic




  {                                                                                  }
      def take(n) {
          [pills: { of ‐>
              [chloroquinine: { after ‐>
                  ['6': { time ‐> }]
              }]
          }]
      }

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



            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge       15
Command chains expressions




          @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens
 select all  unique() from names




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms


           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
     (      ).    (           ).   (      )

 // leverage named‐args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
     (      ).    (           ).   (      )

 // leverage named‐args as punctuation
 check that: margarita  tastes good
      (               ).      (    )

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero‐arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
     (      ).    (           ).   (      )

 // leverage named‐args as punctuation
 check that: margarita  tastes good
      (               ).      (    )

 // closure parameters for new control structures
 given {}  when {}  then {}
      (  ).    (  ).    (  )

 // zero‐arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
     (      ).    (           ).   (      )

 // leverage named‐args as punctuation
 check that: margarita  tastes good
      (               ).      (    )

 // closure parameters for new control structures
 given {}  when {}  then {}
      (  ).    (  ).    (  )

 // zero‐arg methods require parens
 select all  unique() from names
       (   ).        .    (     )

 // possible with an odd number of terms
 take 3  cookies

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
     (      ).    (           ).   (      )

 // leverage named‐args as punctuation
 check that: margarita  tastes good
      (               ).      (    )

 // closure parameters for new control structures
 given {}  when {}  then {}
      (  ).    (  ).    (  )

 // zero‐arg methods require parens
 select all  unique() from names
       (   ).        .    (     )

 // possible with an odd number of terms
 take 3  cookies
     ( ).

           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
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




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   17
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...




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   18
Closure enhancements


• Closure annotation parameters

• Some more functional flavor
  – composition
  – trampoline
  – memoization


• Currying improvements




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   19
Closure annotation parameters
    @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)

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   20
Closure annotation parameters
    @Retention(RetentionPolicy.RUNTIME)
    @interface Invariant {    
        Class value() // a closure class
    }
     

{   @Invariant({ number >= 0 })
    class Distance {    
        float number                   an’s G
                                              Cont racts
        String unit            P oor-m
    } 
     
    def d = new Distance(number: 10, unit: "meters") 
    def anno = Distance.getAnnotation(Invariant)
    def check = anno.value().newInstance(d, d)
    assert check(d)

              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   20
Closure composition

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

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   21
Closure trampoline




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   22
Closure trampoline

 def factorial

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   22
Closure memoization




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)
  




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)
  
 // at most 10 invocations cached




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)
  
 // at most 10 invocations cached
 def plusAtMost = { ... }.memoizeAtMost(10) 




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)
  
 // at most 10 invocations cached
 def plusAtMost = { ... }.memoizeAtMost(10) 

 // between 10 and 20 invocations cached


            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Closure memoization
 def plus = { a, b ‐> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms
 assert plus(1, 2) == 3 // return immediately
 assert plus(2, 2) == 4 // after 1000ms
 assert plus(2, 2) == 4 // return immediately  
  
 // at least 10 invocations cached
 def plusAtLeast = { ... }.memoizeAtLeast(10)
  
 // at most 10 invocations cached
 def plusAtMost = { ... }.memoizeAtMost(10) 

 // between 10 and 20 invocations cached
 def plusAtLeast = { ... }.memoizeBetween(10, 20)

            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   23
Currying improvements




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   24
Currying improvements

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   24
Currying improvements

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


           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   24
Builtin JSON support


• Consuming

• Producing

• Pretty-printing




                    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   25
Builtin JSON support

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 }




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   26
Builtin JSON support

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


           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   27
Builtin JSON support
  import groovy.json.* 
   
  println JsonOutput.prettyPrint(
      '''{"person":{"name":"Guillaume","age":33,''' + 
      '''"pets":["Hector","Felix"]}}''')
   




              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   28
Builtin JSON support
  import groovy.json.* 
   
  println JsonOutput.prettyPrint(
      '''{"person":{"name":"Guillaume","age":33,''' + 
      '''"pets":["Hector","Felix"]}}''')
   

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


              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   28
New AST transformations

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

• @AutoClone
• @AutoExternalizable                         • @InheritConstructor

                                              • @WithReadLock
• Controlling the execution of
  your code                                   • @WithWriteLock
  – @ThreadInterrupt,
  – @TimedInterrupt,                          • @ListenerList
  – @ConditionalInterrupt
                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   29
@Log

• Four different loggers can be injected
  – @Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy

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


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

• Four different loggers can be injected
  – @Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy

                 import groovy.util.logging.* 
                  
                 @Log
                 class Car {    
   Guarded           Car() {        
   w/ an if              log.info 'Car constructed'  
                                                     
                     }
                 } 
                  
                 def c = new Car()


                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   30
@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

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



                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   31
Controlling code execution

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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   32
Controlling code execution

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


• 3 new transforms at your rescue
  – @ThreadInterrupt: adds Thread#isInterrupted checks so your
    executing thread stops when interrupted
  – @TimedInterrupt: adds checks in method and closure bodies to
    verify itʼs run longer than expected
  – @ConditionalInterrupt: adds checks with your own conditional
    logic to break out from the user code




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   32
Controlling code execution

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


• 3 new transforms at your rescue
  – @ThreadInterrupt: adds Thread#isInterrupted checks so your
    executing thread stops when interrupted
  – @TimedInterrupt: adds checks in method and closure bodies to
    verify itʼs run longer than expected
  – @ConditionalInterrupt: adds checks with your own conditional
    logic to break out from the user code




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   32
Controlling code execution

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


• 3 new transforms at your rescue
  – @ThreadInterrupt: adds Thread#isInterrupted checks so your
    executing thread stops when interrupted
  – @TimedInterrupt: adds checks in method and closure bodies to
    verify itʼs run longer than expected
  – @ConditionalInterrupt: adds checks with your own conditional
    logic to break out from the user code


• Also see compilation customizers later on
                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   32
@ThreadInterrupt

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


         // eat lots of CPU
     }




                                                                                      33


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

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

  {       if (Thread.currentThread.isInterrupted())
              throw new InterruptedException()                                         }
          // eat lots of CPU
      }




                                                                                           33


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

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

   {       if (Thread.currentThread.isInterrupted())
               throw new InterruptedException()                                          }
           // eat lots of CPU
       }


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

                                                                                             33


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

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

• 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)

                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   34
@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

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

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


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

• Provides a default toString() method to your types
• Available annotation options
  – includeNames, includeFields, includeSuper, excludes

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


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

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

          import groovy.transform.EqualsAndHashCode 
           
          @EqualsAndHashCode
          class Coord {    
              int x, y
          } 
           
          def c1 = new Coord(x: 20, y: 5)
          def c2 = new Coord(x: 20, y: 5) 
           
          assert c1 == c2
          assert c1.hashCode() == c2.hashCode()




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

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

         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


                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   38
@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




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

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




class CustomException extends Exception {
    CustomException()                        { super()       }
    CustomException(String msg)              { super(msg)    }
    CustomException(String msg, Throwable t) { super(msg, t) }
    CustomException(Throwable t)             { super(t)      }
}




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

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


import groovy.transform.*

@InheritConstructors
class CustomException extends Exception {
    CustomException()                        { super()       }
    CustomException(String msg)              { super(msg)    }
    CustomException(String msg, Throwable t) { super(msg, t) }
    CustomException(Throwable t)             { super(t)      }
}




               @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   40
@WithReadLock, @WithWriteLock

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



              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   41
@WithReadLock, @WithWriteLock

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



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



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




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   42
Compilation customizers


• Ability to apply some customization to the Groovy
  compilation process

• Three available customizers
  – ImportCustomizer
  – ASTTransformationCustomizer
  – SecureASTCustomizer


• But you can implement your own



                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   43
Imports customizer


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




            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   44
Applying an AST transformation

    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()
    """)



            @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   45
Secure AST customizer

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


• Letʼs setup our environment
  – some imports
  – an import customizer to import java.lang.Math.*
  – prepare a secure AST customizer
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()


                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   46
Secure AST customizer

 ...
 secure.with {
   // disallow closure creation
   closuresAllowed = false 
   // disallow method definitions
   methodDefinitionAllowed = false 
  
   // empty white list => forbid imports
   importsWhitelist = [] 
   staticImportsWhitelist = []
   // only allow the java.lang.Math.* static import
   staticStarImportsWhitelist = ['java.lang.Math'
 ...



             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   47
Secure AST customizer
...
   // language tokens allowed
   tokensWhitelist = [
      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 calls
   receiversClassesWhiteList = [ 
      Math, Integer, Float, Double, Long, BigDecimal ]
}
...

                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   48
Secure AST customizer

• Ready to evaluate our arithmetic expressions!
    ...
    def config = new CompilerConfiguration()
    config.addCompilationCustomizers(imports, secure)

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



• But the following would have failed:
            shell.evaluate 'System.exit(0)'


                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   49
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
          def (name, date) = ["Guillaume", "Oct, 26th"]
          def dollarSlashy = $/    
              Hello $name, today we're ${date}
              $ dollar‐sign    
              $$ dollar‐sign    
               backslash    
              / slash    
             $/ slash
          /$ 


                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   50
New GDK methods




         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count




              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }
   assert [(true):2, (false):4] 
       == 'Groovy'.toList().countBy{ it == 'o' }




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 }
   assert [(true):2, (false):4] 
       == 'Groovy'.toList().countBy{ it == 'o' }
    




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def map = [a: 1, bbb: 4, cc: 5, dddd: 2] 




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def map = [a: 1, bbb: 4, cc: 5, dddd: 2] 
   assert map.max { it.key.size() }.key == 'dddd'




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def map = [a: 1, bbb: 4, cc: 5, dddd: 2] 
   assert map.max { it.key.size() }.key == 'dddd'
   assert map.min { it.value }.value == 1




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def map = [a: 1, bbb: 4, cc: 5, dddd: 2] 
   assert map.max { it.key.size() }.key == 'dddd'
   assert map.min { it.value }.value == 1
    




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def 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()




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def 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()




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def 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 }



             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
New GDK methods
   // count
   assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5
    
   // count by
   assert [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
   def 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 }

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   51
(G)String to Enum coercion




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

         enum Color {    




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

         enum Color {    
             red, green, blue




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

         enum Color {    
             red, green, blue
         } 




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

         enum Color {    
             red, green, blue
         } 
          




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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



           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
(G)String to Enum coercion

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


           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   52
Customizing the Groovysh prompt




           @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   53
Launching remote scripts


• With the Groovy command, you can launch remote scripts
 > groovy http://groovyconsole.appspot.com/raw/110001




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




                @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   54
What’s
cooking
for 1.9?
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!



                    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   56
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!



                    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   56
Java 7 / JDK 7

• Project Coin and InvokeDynamic




              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   57
Binary literals

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

• We can now use binary representations too

             int x = 0b10101111
             assert x == 175
              
             byte aByte = 0b00100001
             assert aByte == 33
              
             int anInt = 0b1010000101000101
             assert anInt == 41285


              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   58
Underscore in literals


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

   long creditCardNumber = 1234_5678_9012_3456L
   long socialSecurityNumbers = 999_99_9999L
   float monetaryAmount = 12_345_132.12
   long hexBytes = 0xFF_EC_DE_5E
   long hexWords = 0xFFEC_DE5E
   long maxLong = 0x7fff_ffff_ffff_ffffL
   long alsoMaxLong = 9_223_372_036_854_775_807L
   long bytes = 0b11010010_01101001_10010100_10010010




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


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


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




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   60
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



                   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   61
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.




                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   62
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...

                  @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   63
A typo in your variable or method names

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




              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   64
A typo in your variable or method names

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




              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge      64
Complain on wrong assignments

// 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 = 0
i += '1'




               @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   65
Complain on wrong assignments

// cannot assign value of type... to variable...
int x = new Object()
Set set = new Object()                                                           Compilation
                                                                                 errors!
def o = new Object()
int x = o
 
String[] strings = ['a','b','c']
int str = strings[0]
 
// cannot find matching method plus()
int i = 0
i += '1'




               @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge      65
Complain on wrong return types
String method() { 'String' }
// cannot assign value of type String...
int x = method()

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


              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   66
Complain on wrong return types
String method() { 'String' }
// cannot assign value of type String...
int x = method()                                                               Compilation
                                                                               errors!
// checks if/else branch return values
int method() {
    if (true) { 'String' }
    else { 42 }
}
// works for switch/case & try/catch/finally
 
// transparent toString() implied
String greeting(String name) {
    def sb = new StringBuilder()
    sb << "Hi" << name
}


              @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge         66
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
        }
    }


             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   67
Staticly checked method & dynamic method
       @TypeChecked
       String greeting(String name) {
           // call method with dynamic behavior
           // but with proper signature
           generateMarkup(name.toUpperCase())
       }
        
       // usual dynamic behavior
       String generateMarkup(String name) {
           def sw = new StringWriter()
           new MarkupBuilder(sw).html {
               body {
                   div name
               }
           }
           sw.toString()
       }

             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   68
Bytecode viewer

• Groovy Consoleʼs
  bytecode viewer
  from the AST
  browser window
  – select class
    generation phase
  – select a class node




                 @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   69
Disable Global AST transformations
// witout a specific configuration, the AST builder works
def 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 applied
shell = new GroovyShell(config) // <‐‐ with the configuration
shouldFail {
    shell.evaluate(script) // fails
}


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




          @glaforge — http://glaforge.appspot.com
                                                    ROCKS!
                                                    —   http://gplus.to/glaforge   71
Thank you!




                                e
                        L aforg pment
               aume vy Develo
         Guill Groo                   m
         Hea d of           g mail.co
                    aforge@
            mail: gl glaforge                  e
          E          @              o /glaforg
          T witter : http://gplus.t
           Go ogle+:




             @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   72
Q&A — Got questions, Really?
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
•




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

Contenu connexe

Tendances

Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Guillaume Laforge
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Guillaume Laforge
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Robert Treat
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
Shaping Optimizer's Search Space
Shaping Optimizer's Search SpaceShaping Optimizer's Search Space
Shaping Optimizer's Search SpaceGerger
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloManageIQ
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAnderson Aguiar
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overviewmarpierc
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeDamien Seguin
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.jsBo-Yi Wu
 
Postgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformPostgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformSungJae Yun
 
Write book in markdown
Write book in markdownWrite book in markdown
Write book in markdownLarry Cai
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated FeaturesMark Niebergall
 
Introduction to Parallel Execution
Introduction to Parallel ExecutionIntroduction to Parallel Execution
Introduction to Parallel ExecutionDoug Burns
 
Java 9-10 What's New
Java 9-10 What's NewJava 9-10 What's New
Java 9-10 What's NewNicola Pedot
 

Tendances (20)

Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
Shaping Optimizer's Search Space
Shaping Optimizer's Search SpaceShaping Optimizer's Search Space
Shaping Optimizer's Search Space
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with Gulp
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overview
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the like
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.js
 
Postgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformPostgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud Platform
 
Write book in markdown
Write book in markdownWrite book in markdown
Write book in markdown
 
Advanced GAR
Advanced GARAdvanced GAR
Advanced GAR
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated Features
 
Introduction to Parallel Execution
Introduction to Parallel ExecutionIntroduction to Parallel Execution
Introduction to Parallel Execution
 
Java 9-10 What's New
Java 9-10 What's NewJava 9-10 What's New
Java 9-10 What's New
 
1. MySql plugins
1. MySql plugins1. MySql plugins
1. MySql plugins
 
Nginx pres
Nginx presNginx pres
Nginx pres
 

Similaire à What's new in Groovy 1.8 and beyond

Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programsBadoo Development
 
Advanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentAdvanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentMike Brittain
 
Hand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebHand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebSugree Phatanapherom
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
GitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementGitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementJohn Anderson
 
Continuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPContinuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPKAI CHU CHUNG
 
Feedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeFeedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeHaja R
 
Android Course - Lesson6
 Android Course - Lesson6 Android Course - Lesson6
Android Course - Lesson6Callum Taylor
 
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)Alessandro Nadalin
 
Don't screw it up: how to build durable web apis
Don't screw it up: how to build durable web apisDon't screw it up: how to build durable web apis
Don't screw it up: how to build durable web apisAlessandro Cinelli (cirpo)
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeMário Almeida
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開KAI CHU CHUNG
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy RESTRestlet
 
Fundamentals of programming finals.ajang
Fundamentals of programming finals.ajangFundamentals of programming finals.ajang
Fundamentals of programming finals.ajangJaricka Angelyd Marquez
 
gRPC with Scala and Swift
gRPC with Scala and SwiftgRPC with Scala and Swift
gRPC with Scala and SwiftMarkus Jura
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTfulgoldoraf
 
Faceted Search – the 120 Million Documents Story
Faceted Search – the 120 Million Documents StoryFaceted Search – the 120 Million Documents Story
Faceted Search – the 120 Million Documents StorySourcesense
 
GroongaアプリケーションをDockerコンテナ化して配布する
GroongaアプリケーションをDockerコンテナ化して配布するGroongaアプリケーションをDockerコンテナ化して配布する
GroongaアプリケーションをDockerコンテナ化して配布するongaeshi
 
The Diabolical Developer's Guide to Surviving Java 9
The Diabolical Developer's Guide to Surviving Java 9The Diabolical Developer's Guide to Surviving Java 9
The Diabolical Developer's Guide to Surviving Java 9jClarity
 

Similaire à What's new in Groovy 1.8 and beyond (20)

Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programs
 
Advanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentAdvanced Topics in Continuous Deployment
Advanced Topics in Continuous Deployment
 
Hand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebHand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWeb
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
GitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementGitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo Management
 
Angboard
AngboardAngboard
Angboard
 
Continuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPContinuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCP
 
Feedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeFeedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCode
 
Android Course - Lesson6
 Android Course - Lesson6 Android Course - Lesson6
Android Course - Lesson6
 
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
Don't screw it up: how to build durable web apis @ PHPDay 2014 in Verona (ITA)
 
Don't screw it up: how to build durable web apis
Don't screw it up: how to build durable web apisDon't screw it up: how to build durable web apis
Don't screw it up: how to build durable web apis
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skype
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy REST
 
Fundamentals of programming finals.ajang
Fundamentals of programming finals.ajangFundamentals of programming finals.ajang
Fundamentals of programming finals.ajang
 
gRPC with Scala and Swift
gRPC with Scala and SwiftgRPC with Scala and Swift
gRPC with Scala and Swift
 
Services web RESTful
Services web RESTfulServices web RESTful
Services web RESTful
 
Faceted Search – the 120 Million Documents Story
Faceted Search – the 120 Million Documents StoryFaceted Search – the 120 Million Documents Story
Faceted Search – the 120 Million Documents Story
 
GroongaアプリケーションをDockerコンテナ化して配布する
GroongaアプリケーションをDockerコンテナ化して配布するGroongaアプリケーションをDockerコンテナ化して配布する
GroongaアプリケーションをDockerコンテナ化して配布する
 
The Diabolical Developer's Guide to Surviving Java 9
The Diabolical Developer's Guide to Surviving Java 9The Diabolical Developer's Guide to Surviving Java 9
The Diabolical Developer's Guide to Surviving Java 9
 

Plus de Guillaume Laforge

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Guillaume Laforge
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Guillaume Laforge
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovyGuillaume Laforge
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Guillaume Laforge
 
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Guillaume Laforge
 
Gaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGroovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGuillaume Laforge
 

Plus de Guillaume Laforge (17)

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovy
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
 
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
 
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
 
Gaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume Laforge
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
 
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGroovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
 

Dernier

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 

Dernier (20)

Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 

What's new in Groovy 1.8 and beyond

  • 1. Whatʼs new in Groovy 1.8 and beyond? Guillaume Laforge Groovy Project Manager SpringSource, a division of VMware Twitter: @glaforge Blog: http://glaforge.appspot.com Google+: http://gplus.to/glaforge
  • 2. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 2
  • 3. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 2
  • 4. Groovy 1.7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 5. Groovy 1.7 185 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 6. Groovy 1.7 185k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 7. Groovy 1.7 185k FIRST MONTH AFTER RELEASE @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 8. Groovy 1.7 k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 9. Groovy 1.7 177k SECOND MONTH AFTER RELEASE @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 10. Groovy 1.7 k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 11. Groovy 1.7 362k USERS? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  • 13. Guesstimate 1/2 Users Million@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 5
  • 14. Agenda @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  • 15. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  • 16. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  • 17. Command chains expressions @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 18. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 19. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 20. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 21. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 22. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) • Letʼs have a look at some examples @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  • 23. Command chains expressions  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  • 24. Command chains expressions Alternation of method names  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  • 25. Command chains expressions Alternation of method names  turn left  then right  and parameters (even named ones) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  • 26. Command chains expressions  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  • 27. Command chains expressions Equivalent to:      (    ).    (     )  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  • 28. LookM a! N op are ns, no do ts!
  • 29. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  • 30. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  • 31. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  • 32. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments Woud call: def take(Map m, Quantity q) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  • 33. Command chains expressions Now, even less punctuation! take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
  • 34. Command chains expressions Now, even less punctuation!     (       ).   (             ).      (       ) take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
  • 35. Command chains expressions // environment initialization Integer.metaClass.getPills { ‐> delegate } Integer.metaClass.getHours { ‐> delegate }   // variable injection def chloroquinine = /*...*/   { } // implementing the DSL logic def take(n) {     [of: { drug ‐>         [after: { time ‐> /*...*/ }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2.pills of chloroquinine after 6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 12
  • 36. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
  • 37. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours ... some dots remain ... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
  • 38. Command chains expressions Yes, we can... get rid of them :-) take 2  pills of  chloroquinine  after  6 hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
  • 39. Command chains expressions Yes, we can... get rid of them :-)     ( ).     (  ).              (     ). (     ) take 2  pills of  chloroquinine  after  6 hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
  • 40. Command chains expressions // variable injection def (of, after, hours) = /*...*/   // implementing the DSL logic { } def take(n) {     [pills: { of ‐>         [chloroquinine: { after ‐>             ['6': { time ‐> }]         }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2 pills of chloroquinine after 6 hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 15
  • 41. Command chains expressions @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 42. Command chains expressions // methods with multiple arguments (commas) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 43. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 44. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 45. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 46. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 47. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 48. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 49. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 50. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 51. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 52. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 53. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {} // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 54. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 55. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names       (   ).        .    (     ) // possible with an odd number of terms take 3  cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 56. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor     (      ).    (           ).   (      ) // leverage named‐args as punctuation check that: margarita  tastes good      (               ).      (    ) // closure parameters for new control structures given {}  when {}  then {}      (  ).    (  ).    (  ) // zero‐arg methods require parens select all  unique() from names       (   ).        .    (     ) // possible with an odd number of terms take 3  cookies     ( ). @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 57. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 17
  • 58. 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... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 18
  • 59. Closure enhancements • Closure annotation parameters • Some more functional flavor – composition – trampoline – memoization • Currying improvements @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 19
  • 60. Closure annotation parameters @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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 20
  • 61. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {         Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {         float number     an’s G Cont racts     String unit P oor-m }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 20
  • 62. Closure composition def plus2  = { it + 2 } def times3 = { it * 3 }    { def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 assert times3plus2(4) == plus2(times3(4))    { def plus2times3 = times3 << plus2 assert plus2times3(3) == 15 assert plus2times3(5) == times3(plus2(5))    // reverse composition { assert times3plus2(3) == (times3 >> plus2)(3) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
  • 63. Closure trampoline @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
  • 64. Closure trampoline def factorial factorial = { int n, BigInteger accu = 1G ‐>        if (n < 2) return accu          factorial.trampoline(n ‐ 1, n * accu) }.trampoline()   assert factorial(1)    == 1 assert factorial(3)    == 1 * 2 * 3 assert factorial(1000) == 402387260... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
  • 65. Closure memoization @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 66. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 67. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 68. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 69. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 70. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 71. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 72. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 73. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 74. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 75. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 76. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 77. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  // between 10 and 20 invocations cached @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 78. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  // between 10 and 20 invocations cached def plusAtLeast = { ... }.memoizeBetween(10, 20) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  • 79. Currying improvements @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  • 80. Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  • 81. Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     // currying n‐th parameter def joinWithSeparator =      { one, sep, two ‐> one + sep + two } def joinWithComma =      joinWithSeparator.ncurry(1, ', ') assert joinWithComma('a', 'b') == 'a, b' @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  • 82. Builtin JSON support • Consuming • Producing • Pretty-printing @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 25
  • 84. Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {         name "Guillaume"     age 33         pets "Hector", "Felix" }  println json.toString() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 27
  • 85. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     '''{"person":{"name":"Guillaume","age":33,''' +      '''"pets":["Hector","Felix"]}}''')   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
  • 86. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     '''{"person":{"name":"Guillaume","age":33,''' +      '''"pets":["Hector","Felix"]}}''')   {         "person": {                 "name": "Guillaume",              "age": 33,                 "pets": [                         "Hector",                         "Felix"                 ]         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
  • 87. New AST transformations • @Log • @Canonical – @ToString, • @Field – @EqualsAndHashCode, – @TupleConstructor • @AutoClone • @AutoExternalizable • @InheritConstructor • @WithReadLock • Controlling the execution of your code • @WithWriteLock – @ThreadInterrupt, – @TimedInterrupt, • @ListenerList – @ConditionalInterrupt @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 29
  • 88. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {         Car() {                 log.info 'Car constructed'         } }    def c = new Car() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 30
  • 89. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {     Guarded     Car() {         w/ an if         log.info 'Car constructed'         } }    def c = new Car() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 30
  • 90. @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 @Field List awe = [1, 2, 3] def awesum() { awe.sum() } assert awesum() == 6 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 31
  • 91. Controlling code execution • Your application may run userʼs code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  • 92. Controlling code execution • Your application may run userʼs code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify itʼs run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  • 93. Controlling code execution • Your application may run userʼs code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify itʼs run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  • 94. Controlling code execution • Your application may run userʼs code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify itʼs run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code • Also see compilation customizers later on @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  • 95. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) {     // eat lots of CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  • 96. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  • 97. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } • Two optional annotation parameters available – checkOnMethodStart (true by default) – applyToAllClasses (true by default) 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  • 98. @TimedInterrupt @TimedInterrupt(10) import groovy.transform.TimedInterrupt    while (true) {     // eat lots of CPU } • 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 34
  • 99. @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 @ConditionalInterrupt({ counter++ > 2 }) import groovy.transform.ConditionalInterrupt import groovy.transform.Field    @Field int counter = 0  100.times {         println 'executing script method...' } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 35
  • 100. @ToString • Provides a default toString() method to your types • Available annotation options – includeNames, includeFields, includeSuper, excludes import groovy.transform.ToString    @ToString class Person {         String name         int age }    println new Person(name: 'Pete', age: 15) // => Person(Pete, 15) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 36
  • 101. @EqualsAndHashCode • Provides default implementations for equals() and hashCode() methods import groovy.transform.EqualsAndHashCode    @EqualsAndHashCode class Coord {         int x, y }    def c1 = new Coord(x: 20, y: 5) def c2 = new Coord(x: 20, y: 5)    assert c1 == c2 assert c1.hashCode() == c2.hashCode() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 37
  • 102. @TupleConstructor • Provides a «classical» constructor with all properties • Several annotation parameter options available 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 38
  • 103. @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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 39
  • 104. @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated class CustomException extends Exception {     CustomException()                        { super()       }     CustomException(String msg)              { super(msg)    }     CustomException(String msg, Throwable t) { super(msg, t) }     CustomException(Throwable t)             { super(t)      } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
  • 105. @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated import groovy.transform.* @InheritConstructors class CustomException extends Exception {     CustomException()                        { super()       }     CustomException(String msg)              { super(msg)    }     CustomException(String msg, Throwable t) { super(msg, t) }     CustomException(Throwable t)             { super(t)      } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
  • 106. @WithReadLock, @WithWriteLock 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         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
  • 107. @WithReadLock, @WithWriteLock 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         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
  • 108. Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 42
  • 109. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers – ImportCustomizer – ASTTransformationCustomizer – SecureASTCustomizer • But you can implement your own @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 43
  • 110. Imports customizer def configuration = new CompilerConfiguration()   def custo = new ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)    def result = new GroovyShell(configuration)     .evaluate(" cos PI/3 ") @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 44
  • 111. Applying an AST transformation 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() """) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 45
  • 112. Secure AST customizer Idea: Implement an «arithmetic shell» Being able control what a user script is allowed to do: only arithmetic expressions • Letʼs setup our environment – some imports – an import customizer to import java.lang.Math.* – prepare a secure AST customizer 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 46
  • 113. Secure AST customizer ... secure.with { // disallow closure creation closuresAllowed = false  // disallow method definitions methodDefinitionAllowed = false    // empty white list => forbid imports importsWhitelist = []  staticImportsWhitelist = [] // only allow the java.lang.Math.* static import staticStarImportsWhitelist = ['java.lang.Math' ... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 47
  • 114. Secure AST customizer ... // language tokens allowed tokensWhitelist = [ 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 calls receiversClassesWhiteList = [  Math, Integer, Float, Double, Long, BigDecimal ] } ... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 48
  • 115. Secure AST customizer • Ready to evaluate our arithmetic expressions! ... def config = new CompilerConfiguration() config.addCompilationCustomizers(imports, secure) def shell = new GroovyShell(config)   shell.evaluate 'cos PI/3' • But the following would have failed: shell.evaluate 'System.exit(0)' @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 49
  • 116. 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 def (name, date) = ["Guillaume", "Oct, 26th"] def dollarSlashy = $/         Hello $name, today we're ${date}     $ dollar‐sign         $$ dollar‐sign          backslash         / slash        $/ slash /$  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 50
  • 117. New GDK methods @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 118. New GDK methods // count @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 119. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 120. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 121. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 122. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 123. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == 'Groovy'.toList().countBy{ it == 'o' } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 124. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == 'Groovy'.toList().countBy{ it == 'o' }   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 125. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 126. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 127. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == 'dddd' @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 128. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == 'dddd' assert map.min { it.value }.value == 1 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 129. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == 'dddd' assert map.min { it.value }.value == 1   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 130. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 131. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 132. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 133. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [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 def 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  • 134. (G)String to Enum coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 135. (G)String to Enum coercion enum Color {     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 136. (G)String to Enum coercion enum Color {         red, green, blue @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 137. (G)String to Enum coercion enum Color {         red, green, blue }  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 138. (G)String to Enum coercion enum Color {         red, green, blue }    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 139. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 140. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 141. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 142. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 143. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 144. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 145. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    // with GStrings too @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 146. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    // with GStrings too def g = "${'green'}" as Color @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  • 147. Customizing the Groovysh prompt @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 53
  • 148. Launching remote scripts • With the Groovy command, you can launch remote scripts > groovy http://groovyconsole.appspot.com/raw/110001 • Be careful to what youʼre executing :-) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 54
  • 150. 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! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 56
  • 151. 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! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 56
  • 152. Java 7 / JDK 7 • Project Coin and InvokeDynamic @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 57
  • 153. Binary literals • We had decimal, octal and hexadecimal notations for number literals • We can now use binary representations too int x = 0b10101111 assert x == 175   byte aByte = 0b00100001 assert aByte == 33   int anInt = 0b1010000101000101 assert anInt == 41285 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 58
  • 154. Underscore in literals • Now we can also add underscores in number literals for more readability long creditCardNumber = 1234_5678_9012_3456L long socialSecurityNumbers = 999_99_9999L float monetaryAmount = 12_345_132.12 long hexBytes = 0xFF_EC_DE_5E long hexWords = 0xFFEC_DE5E long maxLong = 0x7fff_ffff_ffff_ffffL long alsoMaxLong = 9_223_372_036_854_775_807L long bytes = 0b11010010_01101001_10010100_10010010 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 59
  • 155. Multicatch • One block for multiple exception caught – rather than duplicating the block try {     /* ... */ } catch(IOException | NullPointerException e) {     /* one block to treat 2 exceptions */ } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 60
  • 156. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 61
  • 157. 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. @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 62
  • 158. 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... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 63
  • 159. A typo in your variable or method names import groovy.transform.StaticTypes   void method() {}   @TypeChecked test() {     // Cannot find matching method metthhoood()     metthhoood()       def name = "Guillaume"     // variable naamme is undeclared     println naamme } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 64
  • 160. A typo in your variable or method names import groovy.transform.StaticTypes   void method() {}   @TypeChecked test() {     // Cannot find matching method metthhoood()     metthhoood()       def name = "Guillaume"     // variable naamme is undeclared Compilation     println naamme errors! } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 64
  • 161. Complain on wrong assignments // 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 = 0 i += '1' @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 65
  • 162. Complain on wrong assignments // cannot assign value of type... to variable... int x = new Object() Set set = new Object() Compilation   errors! def o = new Object() int x = o   String[] strings = ['a','b','c'] int str = strings[0]   // cannot find matching method plus() int i = 0 i += '1' @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 65
  • 163. Complain on wrong return types String method() { 'String' } // cannot assign value of type String... int x = method() // checks if/else branch return values int method() {     if (true) { 'String' }     else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied String greeting(String name) {     def sb = new StringBuilder()     sb << "Hi" << name } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 66
  • 164. Complain on wrong return types String method() { 'String' } // cannot assign value of type String... int x = method() Compilation errors! // checks if/else branch return values int method() {     if (true) { 'String' }     else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied String greeting(String name) {     def sb = new StringBuilder()     sb << "Hi" << name } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 66
  • 165. 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     } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 67
  • 166. Staticly checked method & dynamic method @TypeChecked String greeting(String name) {     // call method with dynamic behavior     // but with proper signature     generateMarkup(name.toUpperCase()) }   // usual dynamic behavior String generateMarkup(String name) {     def sw = new StringWriter()     new MarkupBuilder(sw).html {         body {             div name         }     }     sw.toString() } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 68
  • 167. Bytecode viewer • Groovy Consoleʼs bytecode viewer from the AST browser window – select class generation phase – select a class node @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 69
  • 168. Disable Global AST transformations // witout a specific configuration, the AST builder works def 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 applied shell = new GroovyShell(config) // <‐‐ with the configuration shouldFail {     shell.evaluate(script) // fails } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 70
  • 169. Summary @glaforge — http://glaforge.appspot.com ROCKS! — http://gplus.to/glaforge 71
  • 170. Thank you! e L aforg pment aume vy Develo Guill Groo m Hea d of g mail.co aforge@ mail: gl glaforge e E @ o /glaforg T witter : http://gplus.t Go ogle+: @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 72
  • 171. Q&A — Got questions, Really?
  • 172. 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 • @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 74