SlideShare ist ein Scribd-Unternehmen logo
1 von 119
Downloaden Sie, um offline zu lesen
What’s new in
Groovy 2.0?


 Guillaume Laforge
  Groovy Project Manager
  SpringSource / VMware
     @glaforge
Guillaume Laforge

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


 • Co-author of Groovy in Action
 • Follow me on...
  •   My blog: http://glaforge.appspot.com
  •   Twitter: @glaforge
  •   Google+: http://gplus.to/glaforge
Agenda (1/2)
 • What’s in Groovy 1.8?
  •   Nicer DSLs with command chains
  •   Runtime performance improvements
  •   GPars bundled for taming your multicores
  •   Closure enhancements
  •   Builtin JSON support
  •   New AST transformations
Agenda (2/2)
 • What’s new in Groovy 2.0?
  •   Alignments with JDK 7
      •Project Coin (small language changes)
      •Invoke Dynamic support
          •
         Continued runtime performance improvements
  •   Static type checking
  •   Static compilation
  •   Modularity
Command chains

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


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




          pull	
  request	
  	
  on	
  github	
  
Command chains
             Alternation of
             method names



          pull	
  request	
  	
  on	
  github	
  
Command chains
             Alternation of
             method names



          pull	
  request	
  	
  on	
  github	
  



                       and parameters
                     (even named ones)
Command chains




          pull	
  request	
  	
  on	
  github	
  
Command chains



          Equivalent to:
          	
  	
  	
  	
  (	
  	
  	
  	
  	
  	
  	
  ).	
  	
  (	
  	
  	
  	
  	
  	
  )
          pull	
  request	
  	
  on	
  github	
  
Command chains
Command chains
      //	
  methods	
  with	
  multiple	
  arguments	
  (commas)
Command chains
      //	
  methods	
  with	
  multiple	
  arguments	
  (commas)
      take	
  coffee	
  	
  with	
  sugar,	
  milk	
  	
  and	
  liquor
Command chains
      //	
  methods	
  with	
  multiple	
  arguments	
  (commas)
      take	
  coffee	
  	
  with	
  sugar,	
  milk	
  	
  and	
  liquor

      //	
  leverage	
  named-­‐args	
  as	
  punctuation
Command chains
      //	
  methods	
  with	
  multiple	
  arguments	
  (commas)
      take	
  coffee	
  	
  with	
  sugar,	
  milk	
  	
  and	
  liquor

      //	
  leverage	
  named-­‐args	
  as	
  punctuation
      check	
  that:	
  margarita	
  	
  tastes	
  good
Command chains
      //	
  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
Command chains
      //	
  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	
  {}
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
Command chains
      //	
  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
      	
  	
  	
  	
  (	
  ).
GPars bundled

 • GPars is bundled in the Groovy distribution
 • GPars covers a wide range of parallel
   and concurrent paradigms
  •   actors, fork/join, map/filter/reduce, dataflow, agents
  •   parallel arrays, executors, STM, and more...


 • And you can use it from plain Java as well!
 • http://gpars.codehaus.org/
Closure enhancements
 • Closure annotation parameters
 • Some more functional flavor
  •   composition
      • compose several closures into one single closure
  •   trampoline
    •   avoid stack overflow errors for recursive algorithms
  •   memoization
    •   remember the outcome of previous closure invocations
  •   currying improvements
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)
Closure annotation parameters
       @Retention(RetentionPolicy.RUNTIME)
       @interface	
  Invariant	
  {	
  	
  	
  	
  
       	
  	
  	
  	
  Class	
  value()	
  //	
  a	
  closure	
  class
       }
       	
  
                                                                                       Contr acts
   {   @Invariant({	
  number	
  >=	
  0	
  })
       class	
  Distance	
  {	
  	
  	
  	
  
       	
  	
  	
  	
  float	
  number	
  	
  	
  	
  
                                                                       P oor-m an’s   G

       	
  	
  	
  	
  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)
Closure memoization
Closure memoization
         def	
  plus	
  =	
  {	
  a,	
  b	
  -­‐>	
  sleep	
  1000;	
  a	
  +	
  b	
  }.memoize()
Closure memoization
         def	
  plus	
  =	
  {	
  a,	
  b	
  -­‐>	
  sleep	
  1000;	
  a	
  +	
  b	
  }.memoize()

         assert	
  plus(1,	
  2)	
  ==	
  3	
  //	
  after	
  1000ms
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
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
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	
  	
  
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	
  	
  
         	
  
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
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)
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)
         	
  
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
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)	
  
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
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)
Builtin JSON support

 • Consuming
 • Producing
 • Pretty-printing
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	
  }
Builtin JSON support
  import	
  groovy.json.*	
  
  	
  
  def	
  json	
  =	
  new	
  JsonBuilder()	
  
  	
  
  json.person	
  {	
  	
  	
  	
  
  	
  	
  	
  	
  name	
  "Guillaume"
  	
  	
  	
  	
  age	
  35	
  	
  	
  	
  
  	
  	
  	
  	
  pets	
  "Hector",	
  "Felix"
  }	
  
  println	
  json.toString()
Builtin JSON support
  import	
  groovy.json.*	
  
  	
  
  def	
  json	
  =	
  new	
  JsonBuilder()	
  
  	
                                             {	
  	
  	
  	
  
                                                 	
  	
  	
  	
  "person":	
  {	
  	
  	
  	
  	
  	
  	
  	
  
  json.person	
  {	
  	
  	
  	
  
                                                 	
  	
  	
  	
  	
  	
  	
  	
  "name":	
  "Guillaume",	
  	
  	
  	
                             	
  
  	
  	
  	
  	
  name	
  "Guillaume"            	
  	
  	
  	
  	
  	
  	
  	
  "age":	
  35,	
  	
  	
  	
  	
  	
  	
  	
  
  	
  	
  	
  	
  age	
  35	
  	
  	
  	
        	
  	
  	
  	
  	
  	
  	
  	
  "pets":	
  [	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
  	
  	
  	
  	
  pets	
  "Hector",	
  "Felix"   	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "Hector",	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
                                                                                                                                                   	
  
  }	
                                            	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "Felix"	
  	
  	
  	
  	
  	
  	
  	
  
                                                 	
  	
  	
  	
  	
  	
  	
  	
  ]	
  	
  	
  	
  
  println	
  json.toString()                     	
  	
  	
  	
  }
                                                 }
Builtin JSON support
  import	
  groovy.json.*	
  
  	
  
  println	
  JsonOutput.prettyPrint(
  	
  	
  	
  '{"person":{"name":"Guillaume","age":35,"pets":["Hector","Felix"]}}')

                          {	
  	
  	
  	
  
                          	
  	
  	
  	
  "person":	
  {	
  	
  	
  	
  	
  	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  "name":	
  "Guillaume",	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  "age":	
  35,	
  	
  	
  	
  	
  	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  "pets":	
  [	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "Hector",	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  "Felix"	
  	
  	
  	
  	
  	
  	
  	
  
                          	
  	
  	
  	
  	
  	
  	
  	
  ]	
  	
  	
  	
  
                          	
  	
  	
  	
  }
                          }
New AST transformations
 •       @Log                  •       Controlling execution
                                   •    @ThreadInterrupt

 •       @Field                    •    @TimedInterrupt
                                   •    @ConditionalInterrupt


 •       @AutoClone
                               •       @InheritConstructor
 •       @AutoExternalizable

                               •       @WithReadLock
 •       @Canonical
                               •       @WithWriteLock
     •    @ToString
     •    @EqualsAndHashCode
     •    @TupleConstructor    •       @ListenerList
@Log
 • Four different loggers can be injected
  •   @Log                        import	
  groovy.util.logging.*	
  
  •   @Commons                    	
  
  •   @Log4j                      @Log
                                  class	
  Car	
  {	
  	
  	
  	
  
  •   @Slf4j                      	
  	
  	
  	
  Car()	
  {	
  	
  	
  	
  	
  	
  	
  	
  
                                  	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  'Car	
  constructed'	
  	
  	
  
                                                                                                          	
  
                                  	
  	
  	
  	
  }
 • Possible to implement          }	
  
                                  	
  
   your own strategy              def	
  c	
  =	
  new	
  Car()
@Log
 • Four different loggers can be injected
  •   @Log                        import	
  groovy.util.logging.*	
  
  •   @Commons                    	
  
  •   @Log4j         Guarded
                                  @Log
                                  class	
  Car	
  {	
  	
  	
  	
  
  •   @Slf4j         w/ an if     	
  	
  	
  	
  Car()	
  {	
  	
  	
  	
  	
  	
  	
  	
  
                                  	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  'Car	
  constructed'	
  	
  	
  
                                                                                                          	
  
                                  	
  	
  	
  	
  }
 • Possible to implement          }	
  
                                  	
  
   your own strategy              def	
  c	
  =	
  new	
  Car()
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
@ThreadInterrupt

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


       	
  	
  	
  	
  //	
  eat	
  lots	
  of	
  CPU
       }
@ThreadInterrupt

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

    {   	
  	
  	
  	
  if	
  (Thread.currentThread().isInterrupted())
        	
  	
  	
  	
  	
  	
  	
  	
  throw	
  new	
  InterruptedException()
        	
  	
  	
  	
  //	
  eat	
  lots	
  of	
  CPU
        }
@ToString
 • Provides a default
     toString() method   import	
  groovy.transform.ToString	
  
                         	
  
     to your types       @ToString
 •   Available options   class	
  Person	
  {	
  	
  	
  	
  

  •   includeNames,
                         	
  	
  	
  	
  String	
  name	
  	
  	
  	
  
                         	
  	
  	
  	
  int	
  age
      includeFields,     }	
  
      includeSuper,      	
  
      excludes           println	
  new	
  Person(name:	
  'Pete',	
  age:	
  15)
                         //	
  =>	
  Person(Pete,	
  15)
@EqualsAndHashCode
 • Provides default   import	
  groovy.transform.EqualsAndHashCode	
  
   implementations    	
  
                      @EqualsAndHashCode
   for equals()       class	
  Coord	
  {	
  	
  	
  	
  
   and hashCode()     	
  	
  	
  	
  int	
  x,	
  y
   methods            }	
  
                      	
  
                      def	
  c1	
  =	
  new	
  Coord(x:	
  20,	
  y:	
  5)
                      def	
  c2	
  =	
  new	
  Coord(x:	
  20,	
  y:	
  5)	
  
                      	
  
                      assert	
  c1	
  ==	
  c2
                      assert	
  c1.hashCode()	
  ==	
  c2.hashCode()
@TupleConstructor
 • Provides a « classical »   import	
  groovy.transform.TupleConstructor	
  
     constructor with all     	
  
                              @TupleConstructor	
  
     properties               class	
  Person	
  {	
  	
  	
  	
  
 •   Several annotation       	
  	
  	
  	
  String	
  name	
  	
  	
  	
  
     parameter options        	
  	
  	
  	
  int	
  age
                              }	
  
     available                	
  
                              def	
  m	
  =	
  new	
  Person('Marion',	
  4)	
  	
  	
  	
  	
  	
  
                              	
  
                              assert	
  m.name	
  ==	
  'Marion'
                              assert	
  m.age	
  	
  ==	
  4
@InheritConstructors
 • 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)	
  	
  	
  	
  	
  	
  }
    }
@InheritConstructors
 • 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)	
  	
  	
  	
  	
  	
  }
    }
Compilation customizers

 • Ability to apply some customization to the Groovy compilation
   process


 • Three available customizers
  • ImportCustomizer
  • ASTTransformationCustomizer
  • SecureASTCustomizer
 • But you can implement your own
Imports customizer
       def	
  configuration	
  =	
  new	
  CompilerConfiguration()
       	
  
       def	
  custo	
  =	
  new	
  ImportCustomizer()
       custo.addStaticStar(Math.name)
       configuration.addCompilationCustomizers(custo)	
  
       	
  
       def	
  result	
  =	
  new	
  GroovyShell(configuration)
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  import	
  static	
  java.lang.Math.*
       	
  	
  	
  	
  .evaluate("	
  cos	
  PI/3	
  ")
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  
Miscellaneous

 • Compilation customizers
 • Java 7 diamond operator
 • Slashy and dollar slashy strings
 • New GDK methods
 • (G)String to Enum coercion
 • Customizing the Groovysh prompt
 • Executing remote scripts
Groovy 2.0 bird’s eye view


A more            Java 7       Static Type
                Project Coin   Checking
modular
                  Invoke        Static
Groovy           Dynamic       Compilation
Groovy 2.0 bird’s eye view


A more
modular
Groovy
Groovy Modularity

 • Groovy’s « all » JAR weighs in at 6 MB
 • Nobody needs everything
  •   Template engine, Ant scripting, Swing UI building...


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


 • Provide hooks for setting up DGM methods, etc.
The new JARs

 • A smaller JAR: 3MB
 • Modules     –   console        –   jsr-223     –   test
               –   docgenerator   –   jmx         –   testng
               –   groovydoc      –   sql         –   json
               –   groovysh       –   swing       –   xml
               –   ant            –   servlet
               –   bsf            –   templates
The new JARs

 • A smaller JAR: 3MB
 • Modules     –   console        –   jsr-223     –   test
               –   docgenerator   –   jmx         –   testng
               –   groovydoc      –   sql         –   json
               –   groovysh       –   swing       –   xml
               –   ant            –   servlet
               –   bsf            –   templates
Extension modules

 • Create your own module
  •   contribute instance extension methods
       package	
  foo

       class	
  StringExtension	
  {
       	
  	
  	
  	
  static	
  introduces(String	
  self,	
  String	
  name)	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  "Hi	
  ${name),	
  I’m	
  ${self}"
       	
  	
  	
  	
  }
       }

       //	
  usage:	
  "Guillaume".introduces("Cédric")
Extension modules

 • Create your own module                                                 Same structure
                                                                           as Categories
  •   contribute instance extension methods
       package	
  foo

       class	
  StringExtension	
  {
       	
  	
  	
  	
  static	
  introduces(String	
  self,	
  String	
  name)	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  "Hi	
  ${name),	
  I’m	
  ${self}"
       	
  	
  	
  	
  }
       }

       //	
  usage:	
  "Guillaume".introduces("Cédric")
Extension modules

 • Create your own module
  •   contribute class extension methods

                    package	
  foo

                    class	
  StaticStringExtension	
  {
                    	
  	
  	
  	
  static	
  hi(String	
  self)	
  {
                    	
  	
  	
  	
  	
  	
  	
  	
  "Hi!"
                    	
  	
  	
  	
  }
                    }

                    //	
  usage:	
  String.hi()
Extension module descriptor

 • Descriptor in: META-INF/services/
   org.codehaus.groovy.runtime.ExtensionModule

     moduleName	
  =	
  stringExtensions
     moduleVersion	
  =	
  1.0
     //	
  comma-­‐separated	
  list	
  of	
  classes
     extensionClasses	
  =	
  foo.StringExtension
     //	
  comma-­‐separated	
  list	
  of	
  classes
     staticExtensionClasses	
  =	
  foo.StaticStringExtension
Groovy 2.0 bird’s eye view


A more            Java 7       Static Type
                Project Coin   Checking
modular
                  Invoke        Static
Groovy           Dynamic       Compilation
Groovy 2.0 bird’s eye view

                  Java 7
                Project Coin

                  Invoke
                 Dynamic
Binary literals

  • We had decimal, octal and hexadecimal
      notations for number literals
  •   We can now use binary
                                    int	
  x	
  =	
  0b10101111
      representations too           assert	
  x	
  ==	
  175
                                        	
  
                                        byte	
  aByte	
  =	
  0b00100001
                                        assert	
  aByte	
  ==	
  33
                                        	
  
                                        int	
  anInt	
  =	
  0b1010000101000101
                                        assert	
  anInt	
  ==	
  41285
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
Multicatch

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

        try	
  {
        	
  	
  	
  	
  /*	
  ...	
  */
        }	
  catch(IOException	
  |	
  NullPointerException	
  e)	
  {
        	
  	
  	
  	
  /*	
  one	
  block	
  to	
  treat	
  2	
  exceptions	
  */
        }
InvokeDynamic
 • Groovy 2.0 supports JDK 7’s invokeDynamic
  •   compiler has a flag for compiling against JDK 7
  •   might use the invokeDynamic backport for < JDK 7
 • Benefits
  •    more runtime performance!
      • at least as fast as current « dynamic » Groovy
  •   in the long run, will allow us to get rid of code!
      • call site caching, thanks to MethodHandles
      • metaclass registry, thanks to ClassValues
      • will let the JIT inline calls more easily
Groovy 2.0 bird’s eye view


A more            Java 7       Static Type
                Project Coin   Checking
modular
                  Invoke        Static
Groovy           Dynamic       Compilation
Groovy 2.0 bird’s eye view

                             Static Type
                             Checking
                              Static
                             Compilation
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
Typos in a variable or method
               import	
  groovy.transform.TypeChecked
               	
  
               void	
  method()	
  {}
               	
  
               @TypeChecked	
  test()	
  {
               	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
               	
  	
  	
  	
  metthhoood()
               	
  
               	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
               	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
               	
  	
  	
  	
  println	
  naamme
               }
Typos in a variable or method
               import	
  groovy.transform.TypeChecked
               	
  
               void	
  method()	
  {}
               	
  
               @TypeChecked	
  test()	
  {
               	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
               	
  	
  	
  	
  metthhoood()
               	
  
               	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
Compilation
               	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
     errors!   	
  	
  	
  	
  println	
  naamme
               }
Typos in a variable or method
Annotation can be at     import	
  groovy.transform.TypeChecked
                         	
  
 class or method level
                         void	
  method()	
  {}
                         	
  
                         @TypeChecked	
  test()	
  {
                         	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
                         	
  	
  	
  	
  metthhoood()
                         	
  
                         	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
Compilation
                         	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
     errors!             	
  	
  	
  	
  println	
  naamme
                         }
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'
Wrong assignments
      //	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
      int	
  x	
  =	
  new	
  Object()
      Set	
  set	
  =	
  new	
  Object()                                      Compilation
      	
  
      def	
  o	
  =	
  new	
  Object()
                                                                                errors!
      int	
  x	
  =	
  o
      	
  
      String[]	
  strings	
  =	
  ['a','b','c']
      int	
  str	
  =	
  strings[0]
      	
  
      //	
  cannot	
  find	
  matching	
  method	
  plus()
      int	
  i	
  =	
  0
      i	
  +=	
  '1'
Wrong return types
       //	
  checks	
  if/else	
  branch	
  return	
  values
       @TypeChecked
       int	
  method()	
  {
       	
  	
  	
  	
  if	
  (true)	
  {	
  'String'	
  }
       	
  	
  	
  	
  else	
  {	
  42	
  }
       }
       //	
  works	
  for	
  switch/case	
  &	
  try/catch/finally
       	
  
       //	
  transparent	
  toString()	
  implied
       @TypeChecked
       String	
  greeting(String	
  name)	
  {
       	
  	
  	
  	
  def	
  sb	
  =	
  new	
  StringBuilder()
       	
  	
  	
  	
  sb	
  <<	
  "Hi	
  "	
  <<	
  name
       }
Wrong return types
       //	
  checks	
  if/else	
  branch	
  return	
  values
       @TypeChecked
       int	
  method()	
  {                                     Compilation
       	
  	
  	
  	
  if	
  (true)	
  {	
  'String'	
  }
       	
  	
  	
  	
  else	
  {	
  42	
  }                        error!
       }
       //	
  works	
  for	
  switch/case	
  &	
  try/catch/finally
       	
  
       //	
  transparent	
  toString()	
  implied
       @TypeChecked
       String	
  greeting(String	
  name)	
  {
       	
  	
  	
  	
  def	
  sb	
  =	
  new	
  StringBuilder()
       	
  	
  	
  	
  sb	
  <<	
  "Hi	
  "	
  <<	
  name
       }
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
        	
  	
  	
  	
  }
        }
Statically checked & dynamic methods
           @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()
           }
Instanceof checks
     @TypeChecked	
  
     void	
  test(Object	
  val)	
  {

     	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()
     	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
     	
  	
  	
  	
  }
     }
Instanceof checks
     @TypeChecked	
  
     void	
  test(Object	
  val)	
  {

     	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {                No need
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()            for casts
     	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
     	
  	
  	
  	
  }
     }
Instanceof checks
     @TypeChecked	
  
     void	
  test(Object	
  val)	
  {

     	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {                No need
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()            for casts
     	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
     	
  	
  	
  	
  }
     }


            Can call String#multiply(int)
           from the Groovy Development Kit
Lowest Upper Bound

 • Represents the lowest « super » type classes have in common
  •   may be virtual (aka « non-denotable »)
                   @TypeChecked	
  test()	
  {
                   	
  	
  	
  	
  //	
  an	
  integer	
  and	
  a	
  BigDecimal
                   	
  	
  	
  	
  return	
  [1234,	
  3.14]
                   }
Lowest Upper Bound

 • Represents the lowest « super » type classes have in common
  •   may be virtual (aka « non-denotable »)
                   @TypeChecked	
  test()	
  {
                   	
  	
  	
  	
  //	
  an	
  integer	
  and	
  a	
  BigDecimal
                   	
  	
  	
  	
  return	
  [1234,	
  3.14]
                   }



                        Inferred return type:
                    List<Number & Comparable>
Lowest Upper Bound

 • Represents the lowest « super » type classes have in common
  •   may be virtual (aka « non-denotable »)
                   @TypeChecked	
  test()	
  {
                   	
  	
  	
  	
  //	
  an	
  integer	
  and	
  a	
  BigDecimal
                   	
  	
  	
  	
  return	
  [1234,	
  3.14]
                   }



                        Inferred return type:
                    List<Number & Comparable>
Flow typing

 • Static type checking shouldn’t complain even for bad coding
   practicies which work without type checks
    @TypeChecked	
  test()	
  {
    	
  	
  	
  	
  def	
  var	
  =	
  123	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  inferred	
  type	
  is	
  int
    	
  	
  	
  	
  int	
  x	
  =	
  var	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  var	
  is	
  an	
  int
    	
  	
  	
  	
  var	
  =	
  "123"	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  assign	
  var	
  with	
  a	
  String

    	
  	
  	
  	
  x	
  =	
  var.toInteger()	
  	
  	
  //	
  no	
  problem,	
  no	
  need	
  to	
  cast

    	
  	
  	
  	
  var	
  =	
  123
    	
  	
  	
  	
  x	
  =	
  var.toUpperCase()	
  //	
  error,	
  var	
  is	
  int!
    }
Gotcha: static checking vs dynamic

  • Type checking works at compile-time
   •   adding @TypeChecked doesn’t change behavior
       •do not confuse with static compilation


  • Most dynamic features cannot be type checked
   •   metaclass changes, categories
   •   dynamically bound variables (ex: script’s binding)


  • However, compile-time metaprogramming works
   •   as long as proper type information is defined
Gotcha: runtime metaprogramming

      @TypeChecked	
  
      void	
  test()	
  {
      	
  	
  	
  	
  Integer.metaClass.foo	
  =	
  {}
      	
  	
  	
  	
  123.foo()
      }
Gotcha: runtime metaprogramming

      @TypeChecked	
  
      void	
  test()	
  {
      	
  	
  	
  	
  Integer.metaClass.foo	
  =	
  {}
      	
  	
  	
  	
  123.foo()
      }


                                     Not allowed:
                                  metaClass property
                                     is dynamic
Gotcha: runtime metaprogramming

      @TypeChecked	
  
      void	
  test()	
  {
      	
  	
  	
  	
  Integer.metaClass.foo	
  =	
  {}
      	
  	
  	
  	
  123.foo()
      }


         Method not                  Not allowed:
         recognized               metaClass property
                                     is dynamic
Gotcha: explicit type for closures


   @TypeChecked	
  test()	
  {
   	
  	
  	
  	
  ["a",	
  "b",	
  "c"].collect	
  {
   	
  	
  	
  	
  	
  	
  	
  	
  it.toUpperCase()	
  //	
  Not	
  OK
   	
  	
  	
  	
  }
   }
Gotcha: explicit type for closures


   @TypeChecked	
  test()	
  {
   	
  	
  	
  	
  ["a",	
  "b",	
  "c"].collect	
  {	
  String	
  it	
  -­‐>
   	
  	
  	
  	
  	
  	
  	
  	
  it.toUpperCase()	
  //	
  OK,	
  it’s	
  a	
  String
   	
  	
  	
  	
  }
   }
Closure shared variables


           @TypeChecked	
  test()	
  {
           	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
           	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
           	
  	
  	
  	
  if	
  (random)	
  cl()
           	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
           }
Closure shared variables
                                                              var assigned in the closure:
                                                               « shared closure variable »
           @TypeChecked	
  test()	
  {
           	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
           	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
           	
  	
  	
  	
  if	
  (random)	
  cl()
           	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
           }
Closure shared variables
                                                                    var assigned in the closure:
                                                                     « shared closure variable »
 Impossible to   @TypeChecked	
  test()	
  {
                 	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
  ensure the
                 	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
 assignment      	
  	
  	
  	
  if	
  (random)	
  cl()
really happens   	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
                 }
Closure shared variables
                                                                     var assigned in the closure:
                                                                      « shared closure variable »
 Impossible to    @TypeChecked	
  test()	
  {
                  	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
  ensure the
                  	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
 assignment       	
  	
  	
  	
  if	
  (random)	
  cl()
really happens    	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
                  }


      Only methods of the most specific compatible type
           (LUB) are allowed by the type checker
Closure shared variables
       class	
  A	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {	
  void	
  foo()	
  {}	
  }
       class	
  B	
  extends	
  A	
  {	
  void	
  bar()	
  {}	
  }

       @TypeChecked	
  test()	
  {
       	
  	
  	
  	
  def	
  var	
  =	
  new	
  A()
       	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  B()	
  }
       	
  	
  	
  	
  cl()
       	
  	
  	
  	
  var.foo()	
  	
  	
  //	
  OK!
       }
Closure shared variables
       class	
  A	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {	
  void	
  foo()	
  {}	
  }
       class	
  B	
  extends	
  A	
  {	
  void	
  bar()	
  {}	
  }

       @TypeChecked	
  test()	
  {
       	
  	
  	
  	
  def	
  var	
  =	
  new	
  A()
       	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  B()	
  }
       	
  	
  	
  	
  cl()
       	
  	
  	
  	
  var.foo()	
  	
  	
  //	
  OK!
       }


       var is at least an instance of A
Static Compilation

  • Given your Groovy code can be type checked...
    we can as well compile it « statically »

   •   ie. generate the same byte code as javac


  • Also interesting for those stuck in JDK < 7
    to benefit from performance improvements
Static Compilation: advantages

 • You gain:
  • Type safety
   • thanks to static type checking
    • static compilation builds upon static type checking
  • Faster code
   • as close as possible to Java’s performance
  • Code immune to « monkey patching »
   • metaprogramming badly used can interfere with framework code
  • Smaller bytecode size
Static Compilation: disadvantages

  • But you loose:
   •   Dynamic features
       •metaclass changes, categories, etc.


   •   Dynamic method dispatch
       •although as close as possible to « dynamic » Groovy
Statically compiled & dynamic methods
        @CompileStatic
        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()
        }
What about performance?

 • Comparisons between:
  •   Java


  •   Groovy static compilation (Groovy 2.0)
  •   Groovy with primitive optimizations (Groovy 1.8+)
  •   Groovy without optimizations (Groovy 1.7)
What about performance?
                                                Pi (π)     Binary
                                  Fibonacci
                                              quadrature   trees
                      Java        191 ms       97 ms       3.6 s
                    Static
    1.7 1.8 2.0




                  compilation     197 ms      101 ms       4.3 s
                    Primitive
                  optimizations   360 ms       111 ms      23.7 s
                    No prim.
                  optimizations   2590 ms     3220 ms      50.0 s
Summary: Groovy 2.0 themes
 • Modularity
 • Embark the JDK 7 enhancements
  • Project Coin
  • Invoke Dynamic
 • Static aspects
  • Static type checking
  • Static compilation
Thank you!



                                  ge
                           e Lafor lopment
             Gu illaum ovy Deve
                       Gro
             H ead of
                                         om
                             ge@ gmail.c
                    : glafor forge
              Email @gla                       orge
                        :              .to/glaf om
              Twitter : http://gplus spot.c
                          +             pp
               Google p://glaforge.a
                         tt
                Blog: h
Q&A
Roadmap

 • Groovy 2.1 — end of year            • Groovy 3.0 — 2013
  •   @DelegatesTo annotation, for      •   new Meta-Object Protocol
      better tooling & type checking
                                        •   Java 8 lambda support
  •   complete the invoke dynamic
      support
  •   custom type checking for your
                                       • Groovy 4.0 — 2014
      Domain-Specific Languages
  •   meta-annotations for              •   moving to Antlr 4
      combining AST                     •   rewrite of the grammar
      transformations

Weitere ähnliche Inhalte

Was ist angesagt?

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
 
Ten mistakes functional java
Ten mistakes functional javaTen mistakes functional java
Ten mistakes functional javaBrian Vermeer
 
Ten common mistakes made in Function Java
Ten common mistakes made in Function JavaTen common mistakes made in Function Java
Ten common mistakes made in Function JavaBrian Vermeer
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitBrian Vermeer
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Brian Vermeer
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjugBrian Vermeer
 
Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Brian Vermeer
 
Athenticated smaba server config with open vpn
Athenticated smaba server  config with open vpnAthenticated smaba server  config with open vpn
Athenticated smaba server config with open vpnChanaka Lasantha
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automationLarry Nung
 
Upgrading to Rails 3
Upgrading to Rails 3Upgrading to Rails 3
Upgrading to Rails 3juliangiuca
 
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
 
23769377 lab-bgp-juniper
23769377 lab-bgp-juniper23769377 lab-bgp-juniper
23769377 lab-bgp-junipercavang_3004
 
Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Timote Lima
 

Was ist angesagt? (20)

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
 
Ten mistakes functional java
Ten mistakes functional javaTen mistakes functional java
Ten mistakes functional java
 
Ten common mistakes made in Function Java
Ten common mistakes made in Function JavaTen common mistakes made in Function Java
Ten common mistakes made in Function Java
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java Summit
 
Advanced GAR
Advanced GARAdvanced GAR
Advanced GAR
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
 
Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18
 
Centos config
Centos configCentos config
Centos config
 
Adb instructions
Adb instructionsAdb instructions
Adb instructions
 
Hadoop completereference
Hadoop completereferenceHadoop completereference
Hadoop completereference
 
Athenticated smaba server config with open vpn
Athenticated smaba server  config with open vpnAthenticated smaba server  config with open vpn
Athenticated smaba server config with open vpn
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automation
 
Upgrading to Rails 3
Upgrading to Rails 3Upgrading to Rails 3
Upgrading to Rails 3
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007
 
Refcard en-a4
Refcard en-a4Refcard en-a4
Refcard en-a4
 
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
 
23769377 lab-bgp-juniper
23769377 lab-bgp-juniper23769377 lab-bgp-juniper
23769377 lab-bgp-juniper
 
Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)
 

Andere mochten auch

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
 
Introduction au langage de script Groovy
Introduction au langage de script GroovyIntroduction au langage de script Groovy
Introduction au langage de script GroovyEric Reboisson
 
[GAB2016] NodeJS dans Azure - Matthieu Bouilloux
[GAB2016] NodeJS dans Azure - Matthieu Bouilloux[GAB2016] NodeJS dans Azure - Matthieu Bouilloux
[GAB2016] NodeJS dans Azure - Matthieu BouillouxCellenza
 
Domain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyDomain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyGuillaume 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
 
Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009JUG Lausanne
 
Alter Way's digitalks - Docker : des conteneurs pour tout faire ?
Alter Way's digitalks - Docker  : des conteneurs pour tout faire ? Alter Way's digitalks - Docker  : des conteneurs pour tout faire ?
Alter Way's digitalks - Docker : des conteneurs pour tout faire ? ALTER WAY
 
Serveur web / Base de donnees Langages de développement
Serveur web / Base de donnees Langages de développementServeur web / Base de donnees Langages de développement
Serveur web / Base de donnees Langages de développementLudovic REUS
 
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUGAntonio Gomes Rodrigues
 
Nginx - Serveur HTTP haute performances
Nginx - Serveur HTTP haute performancesNginx - Serveur HTTP haute performances
Nginx - Serveur HTTP haute performancesPascal Armand
 
JUGL 2009 - Introduction Groovy/Grails
JUGL 2009 - Introduction Groovy/GrailsJUGL 2009 - Introduction Groovy/Grails
JUGL 2009 - Introduction Groovy/Grailscyrilpicat
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation GroovyJS Bournival
 
Déploiement et gestion d'un site web avec Rancher
Déploiement et gestion d'un site web avec RancherDéploiement et gestion d'un site web avec Rancher
Déploiement et gestion d'un site web avec RancherAnthony Sigogne
 
DevFest Nantes 2016 - Spinnaker
DevFest Nantes 2016 - SpinnakerDevFest Nantes 2016 - Spinnaker
DevFest Nantes 2016 - SpinnakerStephan Lagraulet
 
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...Introduction à Docker et utilisation en production /Digital apéro Besançon [1...
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...Silicon Comté
 
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]Silicon Comté
 

Andere mochten auch (20)

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
 
Gradle
GradleGradle
Gradle
 
Introduction au langage de script Groovy
Introduction au langage de script GroovyIntroduction au langage de script Groovy
Introduction au langage de script Groovy
 
[GAB2016] NodeJS dans Azure - Matthieu Bouilloux
[GAB2016] NodeJS dans Azure - Matthieu Bouilloux[GAB2016] NodeJS dans Azure - Matthieu Bouilloux
[GAB2016] NodeJS dans Azure - Matthieu Bouilloux
 
Domain-Specific Languages avec Groovy
Domain-Specific Languages avec GroovyDomain-Specific Languages avec Groovy
Domain-Specific Languages avec Groovy
 
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
 
Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009Introduction Groovy / Grails - Cyril Picat - December 2009
Introduction Groovy / Grails - Cyril Picat - December 2009
 
Alter Way's digitalks - Docker : des conteneurs pour tout faire ?
Alter Way's digitalks - Docker  : des conteneurs pour tout faire ? Alter Way's digitalks - Docker  : des conteneurs pour tout faire ?
Alter Way's digitalks - Docker : des conteneurs pour tout faire ?
 
Serveur web / Base de donnees Langages de développement
Serveur web / Base de donnees Langages de développementServeur web / Base de donnees Langages de développement
Serveur web / Base de donnees Langages de développement
 
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG
"Apache JMeter, Java et Groovy sont sur un bateau" présentée au Paris JUG
 
Nginx - Serveur HTTP haute performances
Nginx - Serveur HTTP haute performancesNginx - Serveur HTTP haute performances
Nginx - Serveur HTTP haute performances
 
Nginx
NginxNginx
Nginx
 
JUGL 2009 - Introduction Groovy/Grails
JUGL 2009 - Introduction Groovy/GrailsJUGL 2009 - Introduction Groovy/Grails
JUGL 2009 - Introduction Groovy/Grails
 
Présentation Groovy
Présentation GroovyPrésentation Groovy
Présentation Groovy
 
Déploiement et gestion d'un site web avec Rancher
Déploiement et gestion d'un site web avec RancherDéploiement et gestion d'un site web avec Rancher
Déploiement et gestion d'un site web avec Rancher
 
DevFest Nantes 2016 - Spinnaker
DevFest Nantes 2016 - SpinnakerDevFest Nantes 2016 - Spinnaker
DevFest Nantes 2016 - Spinnaker
 
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...Introduction à Docker et utilisation en production /Digital apéro Besançon [1...
Introduction à Docker et utilisation en production /Digital apéro Besançon [1...
 
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]
Docker ! De la découverte à la mise en production / Digital apéro [19/03/2015]
 

Mehr von Guillaume 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
 
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 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
 
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
 

Mehr von Guillaume Laforge (16)

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
 
Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
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
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
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...
 
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
 

Kürzlich hochgeladen

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
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
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
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
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
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
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 

Kürzlich hochgeladen (20)

Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
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
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
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
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
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
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 

Groovy 2.0 update at Devoxx 2012

  • 1. What’s new in Groovy 2.0? Guillaume Laforge Groovy Project Manager SpringSource / VMware @glaforge
  • 2. Guillaume Laforge • Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk • Co-author of Groovy in Action • Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge
  • 3. Agenda (1/2) • What’s in Groovy 1.8? • Nicer DSLs with command chains • Runtime performance improvements • GPars bundled for taming your multicores • Closure enhancements • Builtin JSON support • New AST transformations
  • 4. Agenda (2/2) • What’s new in Groovy 2.0? • Alignments with JDK 7 •Project Coin (small language changes) •Invoke Dynamic support • Continued runtime performance improvements • Static type checking • Static compilation • Modularity
  • 5. Command chains • A grammar improvement allowing you to drop dots & parens when chaining method calls • an extended version of top-level statements like println • Less dots, less parens allow you to • write more readable business rules • in almost plain English sentences • (or any language, of course)
  • 6. Command chains pull  request    on  github  
  • 7. Command chains Alternation of method names pull  request    on  github  
  • 8. Command chains Alternation of method names pull  request    on  github   and parameters (even named ones)
  • 9. Command chains pull  request    on  github  
  • 10. Command chains Equivalent to:        (              ).    (            ) pull  request    on  github  
  • 12. Command chains //  methods  with  multiple  arguments  (commas)
  • 13. Command chains //  methods  with  multiple  arguments  (commas) take  coffee    with  sugar,  milk    and  liquor
  • 14. Command chains //  methods  with  multiple  arguments  (commas) take  coffee    with  sugar,  milk    and  liquor //  leverage  named-­‐args  as  punctuation
  • 15. Command chains //  methods  with  multiple  arguments  (commas) take  coffee    with  sugar,  milk    and  liquor //  leverage  named-­‐args  as  punctuation check  that:  margarita    tastes  good
  • 16. Command chains //  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
  • 17. Command chains //  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  {}
  • 18. Command chains //  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
  • 19. Command chains //  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
  • 20. Command chains //  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
  • 21. Command chains //  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
  • 22. Command chains //  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
  • 23. Command chains //  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
  • 24. Command chains //  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
  • 25. Command chains //  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
  • 26. Command chains //  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        (  ).
  • 27. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms • actors, fork/join, map/filter/reduce, dataflow, agents • parallel arrays, executors, STM, and more... • And you can use it from plain Java as well! • http://gpars.codehaus.org/
  • 28. Closure enhancements • Closure annotation parameters • Some more functional flavor • composition • compose several closures into one single closure • trampoline • avoid stack overflow errors for recursive algorithms • memoization • remember the outcome of previous closure invocations • currying improvements
  • 29. 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)
  • 30. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface  Invariant  {                Class  value()  //  a  closure  class }   Contr acts { @Invariant({  number  >=  0  }) class  Distance  {                float  number         P oor-m an’s G        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)
  • 32. Closure memoization def  plus  =  {  a,  b  -­‐>  sleep  1000;  a  +  b  }.memoize()
  • 33. Closure memoization def  plus  =  {  a,  b  -­‐>  sleep  1000;  a  +  b  }.memoize() assert  plus(1,  2)  ==  3  //  after  1000ms
  • 34. 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
  • 35. 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
  • 36. 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    
  • 37. 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      
  • 38. 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
  • 39. 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)
  • 40. 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)  
  • 41. 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
  • 42. 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)  
  • 43. 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
  • 44. 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)
  • 45. Builtin JSON support • Consuming • Producing • Pretty-printing
  • 46. 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  }
  • 47. Builtin JSON support import  groovy.json.*     def  json  =  new  JsonBuilder()     json.person  {                name  "Guillaume"        age  35                pets  "Hector",  "Felix" }   println  json.toString()
  • 48. Builtin JSON support import  groovy.json.*     def  json  =  new  JsonBuilder()     {                "person":  {                 json.person  {                        "name":  "Guillaume",                  name  "Guillaume"                "age":  35,                        age  35                        "pets":  [                                pets  "Hector",  "Felix"                        "Hector",                         }                          "Felix"                                ]         println  json.toString()        } }
  • 49. Builtin JSON support import  groovy.json.*     println  JsonOutput.prettyPrint(      '{"person":{"name":"Guillaume","age":35,"pets":["Hector","Felix"]}}') {                "person":  {                                "name":  "Guillaume",                      "age":  35,                                "pets":  [                                                "Hector",                                            "Felix"                                ]                } }
  • 50. New AST transformations • @Log • Controlling execution • @ThreadInterrupt • @Field • @TimedInterrupt • @ConditionalInterrupt • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • @Canonical • @WithWriteLock • @ToString • @EqualsAndHashCode • @TupleConstructor • @ListenerList
  • 51. @Log • Four different loggers can be injected • @Log import  groovy.util.logging.*   • @Commons   • @Log4j @Log class  Car  {         • @Slf4j        Car()  {                                log.info  'Car  constructed'                } • Possible to implement }     your own strategy def  c  =  new  Car()
  • 52. @Log • Four different loggers can be injected • @Log import  groovy.util.logging.*   • @Commons   • @Log4j Guarded @Log class  Car  {         • @Slf4j w/ an if        Car()  {                                log.info  'Car  constructed'                } • Possible to implement }     your own strategy def  c  =  new  Car()
  • 53. 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
  • 54. @ThreadInterrupt @ThreadInterrupt import  groovy.transform.ThreadInterrupt     while  (true)  {        //  eat  lots  of  CPU }
  • 55. @ThreadInterrupt @ThreadInterrupt import  groovy.transform.ThreadInterrupt     while  (true)  { {        if  (Thread.currentThread().isInterrupted())                throw  new  InterruptedException()        //  eat  lots  of  CPU }
  • 56. @ToString • Provides a default toString() method import  groovy.transform.ToString     to your types @ToString • Available options class  Person  {         • includeNames,        String  name                int  age includeFields, }   includeSuper,   excludes println  new  Person(name:  'Pete',  age:  15) //  =>  Person(Pete,  15)
  • 57. @EqualsAndHashCode • Provides default import  groovy.transform.EqualsAndHashCode   implementations   @EqualsAndHashCode for equals() class  Coord  {         and hashCode()        int  x,  y methods }     def  c1  =  new  Coord(x:  20,  y:  5) def  c2  =  new  Coord(x:  20,  y:  5)     assert  c1  ==  c2 assert  c1.hashCode()  ==  c2.hashCode()
  • 58. @TupleConstructor • Provides a « classical » import  groovy.transform.TupleConstructor   constructor with all   @TupleConstructor   properties class  Person  {         • Several annotation        String  name         parameter options        int  age }   available   def  m  =  new  Person('Marion',  4)               assert  m.name  ==  'Marion' assert  m.age    ==  4
  • 59. @InheritConstructors • 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)            } }
  • 60. @InheritConstructors • 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)            } }
  • 61. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers • ImportCustomizer • ASTTransformationCustomizer • SecureASTCustomizer • But you can implement your own
  • 62. Imports customizer def  configuration  =  new  CompilerConfiguration()   def  custo  =  new  ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)     def  result  =  new  GroovyShell(configuration)                          //  import  static  java.lang.Math.*        .evaluate("  cos  PI/3  ")                            
  • 63. Miscellaneous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion • Customizing the Groovysh prompt • Executing remote scripts
  • 64. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation
  • 65. Groovy 2.0 bird’s eye view A more modular Groovy
  • 66. Groovy Modularity • Groovy’s « all » JAR weighs in at 6 MB • Nobody needs everything • Template engine, Ant scripting, Swing UI building... • Provide a smaller core • and several smaller JARs per feature • Provide hooks for setting up DGM methods, etc.
  • 67. The new JARs • A smaller JAR: 3MB • Modules – console – jsr-223 – test – docgenerator – jmx – testng – groovydoc – sql – json – groovysh – swing – xml – ant – servlet – bsf – templates
  • 68. The new JARs • A smaller JAR: 3MB • Modules – console – jsr-223 – test – docgenerator – jmx – testng – groovydoc – sql – json – groovysh – swing – xml – ant – servlet – bsf – templates
  • 69. Extension modules • Create your own module • contribute instance extension methods package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric")
  • 70. Extension modules • Create your own module Same structure as Categories • contribute instance extension methods package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric")
  • 71. Extension modules • Create your own module • contribute class extension methods package  foo class  StaticStringExtension  {        static  hi(String  self)  {                "Hi!"        } } //  usage:  String.hi()
  • 72. Extension module descriptor • Descriptor in: META-INF/services/ org.codehaus.groovy.runtime.ExtensionModule moduleName  =  stringExtensions moduleVersion  =  1.0 //  comma-­‐separated  list  of  classes extensionClasses  =  foo.StringExtension //  comma-­‐separated  list  of  classes staticExtensionClasses  =  foo.StaticStringExtension
  • 73. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation
  • 74. Groovy 2.0 bird’s eye view Java 7 Project Coin Invoke Dynamic
  • 75. Binary literals • We had decimal, octal and hexadecimal notations for number literals • We can now use binary int  x  =  0b10101111 representations too assert  x  ==  175   byte  aByte  =  0b00100001 assert  aByte  ==  33   int  anInt  =  0b1010000101000101 assert  anInt  ==  41285
  • 76. 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
  • 77. Multicatch • One block for multiple exception caught • rather than duplicating the block try  {        /*  ...  */ }  catch(IOException  |  NullPointerException  e)  {        /*  one  block  to  treat  2  exceptions  */ }
  • 78. InvokeDynamic • Groovy 2.0 supports JDK 7’s invokeDynamic • compiler has a flag for compiling against JDK 7 • might use the invokeDynamic backport for < JDK 7 • Benefits • more runtime performance! • at least as fast as current « dynamic » Groovy • in the long run, will allow us to get rid of code! • call site caching, thanks to MethodHandles • metaclass registry, thanks to ClassValues • will let the JIT inline calls more easily
  • 79. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation
  • 80. Groovy 2.0 bird’s eye view Static Type Checking Static Compilation
  • 81. 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
  • 82. Typos in a variable or method import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme }
  • 83. Typos in a variable or method import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume" Compilation        //  variable  naamme  is  undeclared errors!        println  naamme }
  • 84. Typos in a variable or method Annotation can be at import  groovy.transform.TypeChecked   class or method level void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume" Compilation        //  variable  naamme  is  undeclared errors!        println  naamme }
  • 85. 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'
  • 86. Wrong assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object() Compilation   def  o  =  new  Object() errors! int  x  =  o   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1'
  • 87. Wrong return types //  checks  if/else  branch  return  values @TypeChecked int  method()  {        if  (true)  {  'String'  }        else  {  42  } } //  works  for  switch/case  &  try/catch/finally   //  transparent  toString()  implied @TypeChecked String  greeting(String  name)  {        def  sb  =  new  StringBuilder()        sb  <<  "Hi  "  <<  name }
  • 88. Wrong return types //  checks  if/else  branch  return  values @TypeChecked int  method()  { Compilation        if  (true)  {  'String'  }        else  {  42  } error! } //  works  for  switch/case  &  try/catch/finally   //  transparent  toString()  implied @TypeChecked String  greeting(String  name)  {        def  sb  =  new  StringBuilder()        sb  <<  "Hi  "  <<  name }
  • 89. 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        } }
  • 90. Statically checked & dynamic methods @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() }
  • 91. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } }
  • 92. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  { No need                println  val.toUpperCase() for casts        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } }
  • 93. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  { No need                println  val.toUpperCase() for casts        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } Can call String#multiply(int) from the Groovy Development Kit
  • 94. Lowest Upper Bound • Represents the lowest « super » type classes have in common • may be virtual (aka « non-denotable ») @TypeChecked  test()  {        //  an  integer  and  a  BigDecimal        return  [1234,  3.14] }
  • 95. Lowest Upper Bound • Represents the lowest « super » type classes have in common • may be virtual (aka « non-denotable ») @TypeChecked  test()  {        //  an  integer  and  a  BigDecimal        return  [1234,  3.14] } Inferred return type: List<Number & Comparable>
  • 96. Lowest Upper Bound • Represents the lowest « super » type classes have in common • may be virtual (aka « non-denotable ») @TypeChecked  test()  {        //  an  integer  and  a  BigDecimal        return  [1234,  3.14] } Inferred return type: List<Number & Comparable>
  • 97. Flow typing • Static type checking shouldn’t complain even for bad coding practicies which work without type checks @TypeChecked  test()  {        def  var  =  123                  //  inferred  type  is  int        int  x  =  var                      //  var  is  an  int        var  =  "123"                      //  assign  var  with  a  String        x  =  var.toInteger()      //  no  problem,  no  need  to  cast        var  =  123        x  =  var.toUpperCase()  //  error,  var  is  int! }
  • 98. Gotcha: static checking vs dynamic • Type checking works at compile-time • adding @TypeChecked doesn’t change behavior •do not confuse with static compilation • Most dynamic features cannot be type checked • metaclass changes, categories • dynamically bound variables (ex: script’s binding) • However, compile-time metaprogramming works • as long as proper type information is defined
  • 99. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() }
  • 100. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Not allowed: metaClass property is dynamic
  • 101. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Method not Not allowed: recognized metaClass property is dynamic
  • 102. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {                it.toUpperCase()  //  Not  OK        } }
  • 103. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {  String  it  -­‐>                it.toUpperCase()  //  OK,  it’s  a  String        } }
  • 104. Closure shared variables @TypeChecked  test()  {        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  }        if  (random)  cl()        var.toUpperCase()    //  Not  OK! }
  • 105. Closure shared variables var assigned in the closure: « shared closure variable » @TypeChecked  test()  {        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  }        if  (random)  cl()        var.toUpperCase()    //  Not  OK! }
  • 106. Closure shared variables var assigned in the closure: « shared closure variable » Impossible to @TypeChecked  test()  {        def  var  =  "abc"               ensure the        def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really happens        var.toUpperCase()    //  Not  OK! }
  • 107. Closure shared variables var assigned in the closure: « shared closure variable » Impossible to @TypeChecked  test()  {        def  var  =  "abc"               ensure the        def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really happens        var.toUpperCase()    //  Not  OK! } Only methods of the most specific compatible type (LUB) are allowed by the type checker
  • 108. Closure shared variables class  A                      {  void  foo()  {}  } class  B  extends  A  {  void  bar()  {}  } @TypeChecked  test()  {        def  var  =  new  A()        def  cl  =  {  var  =  new  B()  }        cl()        var.foo()      //  OK! }
  • 109. Closure shared variables class  A                      {  void  foo()  {}  } class  B  extends  A  {  void  bar()  {}  } @TypeChecked  test()  {        def  var  =  new  A()        def  cl  =  {  var  =  new  B()  }        cl()        var.foo()      //  OK! } var is at least an instance of A
  • 110. Static Compilation • Given your Groovy code can be type checked... we can as well compile it « statically » • ie. generate the same byte code as javac • Also interesting for those stuck in JDK < 7 to benefit from performance improvements
  • 111. Static Compilation: advantages • You gain: • Type safety • thanks to static type checking • static compilation builds upon static type checking • Faster code • as close as possible to Java’s performance • Code immune to « monkey patching » • metaprogramming badly used can interfere with framework code • Smaller bytecode size
  • 112. Static Compilation: disadvantages • But you loose: • Dynamic features •metaclass changes, categories, etc. • Dynamic method dispatch •although as close as possible to « dynamic » Groovy
  • 113. Statically compiled & dynamic methods @CompileStatic 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() }
  • 114. What about performance? • Comparisons between: • Java • Groovy static compilation (Groovy 2.0) • Groovy with primitive optimizations (Groovy 1.8+) • Groovy without optimizations (Groovy 1.7)
  • 115. What about performance? Pi (π) Binary Fibonacci quadrature trees Java 191 ms 97 ms 3.6 s Static 1.7 1.8 2.0 compilation 197 ms 101 ms 4.3 s Primitive optimizations 360 ms 111 ms 23.7 s No prim. optimizations 2590 ms 3220 ms 50.0 s
  • 116. Summary: Groovy 2.0 themes • Modularity • Embark the JDK 7 enhancements • Project Coin • Invoke Dynamic • Static aspects • Static type checking • Static compilation
  • 117. Thank you! ge e Lafor lopment Gu illaum ovy Deve Gro H ead of om ge@ gmail.c : glafor forge Email @gla orge : .to/glaf om Twitter : http://gplus spot.c + pp Google p://glaforge.a tt Blog: h
  • 118. Q&A
  • 119. Roadmap • Groovy 2.1 — end of year • Groovy 3.0 — 2013 • @DelegatesTo annotation, for • new Meta-Object Protocol better tooling & type checking • Java 8 lambda support • complete the invoke dynamic support • custom type checking for your • Groovy 4.0 — 2014 Domain-Specific Languages • meta-annotations for • moving to Antlr 4 combining AST • rewrite of the grammar transformations