SlideShare a Scribd company logo
1 of 120
Download to read offline
What’s new in Groovy 2.0?
                                                              Guillaume Laforge
                                                             Groovy Project Manager
                                                             SpringSource / VMware
                                                                          @glaforge

© 2012 SpringOne 2GX. All rights reserved. Do not distribute without permission.
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
2
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




3
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



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



5
Command chains




              pull	
  request	
  	
  on	
  github	
  




6
Command chains
                 Alternation of
                 method names



              pull	
  request	
  	
  on	
  github	
  




6
Command chains
                 Alternation of
                 method names



              pull	
  request	
  	
  on	
  github	
  



                           and parameters
                         (even named ones)

6
Command chains




              pull	
  request	
  	
  on	
  github	
  




6
Command chains



              Equivalent to:
               	
  	
  	
  (	
  	
  	
  	
  	
  	
  	
  ).	
  	
  (	
  	
  	
  	
  	
  	
  )
              pull	
  request	
  	
  on	
  github	
  




6
Command chains




7
Command chains
         //	
  methods	
  with	
  multiple	
  arguments	
  (commas)




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




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

         //	
  leverage	
  named-­‐args	
  as	
  punctuation




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

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




7
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




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




7
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




7
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




7
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




7
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




7
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




7
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




7
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




7
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




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




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

8
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
9
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)



10
Closure annotation parameters
            @Retention(RetentionPolicy.RUNTIME)
            @interface	
  Invariant	
  {	
  	
  	
  	
  
            	
  	
  	
  	
  Class	
  value()	
  //	
  a	
  closure	
  class
            }
            	
  
                                                                                              Cont racts
        {   @Invariant({	
  number	
  >=	
  0	
  })
            class	
  Distance	
  {	
  	
  	
  	
  
            	
  	
  	
  	
  float	
  number	
  	
  	
  	
  
                                                                            Poor-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)



10
Closure memoization




11
Closure memoization
              def	
  plus	
  =	
  {	
  a,	
  b	
  -­‐>	
  sleep	
  1000;	
  a	
  +	
  b	
  }.memoize()




11
Closure memoization
              def	
  plus	
  =	
  {	
  a,	
  b	
  -­‐>	
  sleep	
  1000;	
  a	
  +	
  b	
  }.memoize()

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




11
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




11
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




11
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	
  	
  




11
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	
  	
  
              	
  




11
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




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




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




11
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




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




11
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




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



11
Builtin JSON support

     • Consuming

     • Producing

     • Pretty-printing




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




13
Builtin JSON support

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



14
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()                     	
  	
  	
  	
  }
                                                     }


14
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"	
  	
  	
  	
  	
  	
  	
  	
  
                               	
  	
  	
  	
  	
  	
  	
  	
  ]	
  	
  	
  	
  
                               	
  	
  	
  	
  }
                               }

15
New AST transformations
     • @Log                    • Controlling execution
                                 – @ThreadInterrupt
                                 – @TimedInterrupt
     • @Field
                                 – @ConditionalInterrupt

     • @AutoClone              • @InheritConstructor
     • @AutoExternalizable

                               • @WithReadLock
     • @Canonical
                               • @WithWriteLock
       – @ToString
       – @EqualsAndHashCode
       – @TupleConstructor     • @ListenerList
16
@Log

     • Four different loggers can be injected
       –@Log                           import	
  groovy.util.logging.*	
  
       –@Commons                       	
  
                                       @Log
       –@Log4j                         class	
  Car	
  {	
  	
  	
  	
  
       –@Slf4j                         	
  	
  	
  	
  Car()	
  {	
  	
  	
  	
  	
  	
  	
  	
  
                                       	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  'Car	
  constructed'	
  	
  	
  
                                                                                                               	
  
                                       	
  	
  	
  	
  }
     • Possible to implement           }	
  
                                       	
  
       your own strategy               def	
  c	
  =	
  new	
  Car()


17
@Log

     • Four different loggers can be injected
       –@Log                           import	
  groovy.util.logging.*	
  
       –@Commons                       	
  
                                       @Log
       –@Log4j            Guarded      class	
  Car	
  {	
  	
  	
  	
  
       –@Slf4j            w/ an if     	
  	
  	
  	
  Car()	
  {	
  	
  	
  	
  	
  	
  	
  	
  
                                       	
  	
  	
  	
  	
  	
  	
  	
  log.info	
  'Car	
  constructed'	
  	
  	
  
                                                                                                               	
  
                                       	
  	
  	
  	
  }
     • Possible to implement           }	
  
                                       	
  
       your own strategy               def	
  c	
  =	
  new	
  Car()


17
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
18
@ThreadInterrupt

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


            	
  	
  	
  	
  //	
  eat	
  lots	
  of	
  CPU
            }




19
@ThreadInterrupt

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

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




19
@ToString

     • Provides a default
       toString() method                import	
  groovy.transform.ToString	
  
       to your types                    	
  
                                        @ToString
     • Available options                class	
  Person	
  {	
  	
  	
  	
  
       – includeNames, includeFields,   	
  	
  	
  	
  String	
  name	
  	
  	
  	
  
         includeSuper, excludes         	
  	
  	
  	
  int	
  age
                                        }	
  
                                        	
  
                                        println	
  new	
  Person(name:	
  'Pete',	
  age:	
  15)
                                        //	
  =>	
  Person(Pete,	
  15)



20
@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()


21
@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


22
@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)	
  	
  	
  	
  	
  	
  }
        }


23
@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)	
  	
  	
  	
  	
  	
  }
        }


23
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



24
Compilation customizers
     • Ability to apply some customization to the Groovy compilation
       process

     • Three available customizers
       –ImportCustomizer
       –ASTTransformationCustomizer
       –SecureASTCustomizer


     • But you can implement your own

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


26
What’s
in store
for 2.0?
Groovy 2.0 bird’s eye view


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


                       A more
                       modular
                       Groovy
29
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.
30
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

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

32
Extension modules
     • Create your own module                                              Same structure
      –contribute instance extension methods                               as Categories
          package	
  foo

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

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

32
Extension modules
     • Create your own module
      –contribute class extension methods

                       package	
  foo

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

                       //	
  usage:	
  String.hi()

33
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



34
Groovy 2.0 bird’s eye view


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


                        Java 7
                       Project Coin

                        Invoke
                       Dynamic
36
Java 7 / JDK 7

     • Project Coin and InvokeDynamic




37
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


38
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


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


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



40
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

41
Groovy 2.0 bird’s eye view


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

                      Static Type
                       Checking
                         Static
                      Compilation
43
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
44
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
                     }



45
Typos in a variable or method

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



45
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()
                         	
  
 Compilation             	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
                         	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
      errors!            	
  	
  	
  	
  println	
  naamme
                         }



45
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'


46
Wrong assignments

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


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

47
Wrong return types
            //	
  checks	
  if/else	
  branch	
  return	
  values
            @TypeChecked
            int	
  method()	
  {
            	
  	
  	
  	
  if	
  (true)	
  {	
  'String'	
  }
                                                                     Compilation
            	
  	
  	
  	
  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
            }

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

48
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()
                }

49
Instanceof checks
          @TypeChecked	
  
          void	
  test(Object	
  val)	
  {

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




50
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()
          	
  	
  	
  	
  }
          }




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




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

52
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
53
Gotcha: runtime metaprogramming

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




54
Gotcha: runtime metaprogramming

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

                                       Not allowed:
                                       metaClass property
                                       is dynamic

54
Gotcha: runtime metaprogramming

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

                Method not             Not allowed:
                recognized             metaClass property
                                       is dynamic

54
Gotcha: explicit type for closures

        @TypeChecked	
  test()	
  {
        	
  	
  	
  	
  ["a",	
  "b",	
  "c"].collect	
  {
        	
  	
  	
  	
  	
  	
  	
  	
  it.toUpperCase()	
  //	
  Not	
  OK
        	
  	
  	
  	
  }
        }



     • A « Groovy Enhancement Proposal » to address the issue

55
Gotcha: explicit type for closures

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



     • A « Groovy Enhancement Proposal » to address the issue

55
Closure shared variables


                  @TypeChecked	
  test()	
  {
                  	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
                  	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
                  	
  	
  	
  	
  if	
  (random)	
  cl()
                  	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
                  }




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




56
Closure shared variables
                                                                var assigned in the closure:
                                                                « shared closure variable »

     Impossible to   @TypeChecked	
  test()	
  {
     ensure the      	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
                     	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
     assignment
                     	
  	
  	
  	
  if	
  (random)	
  cl()
     really          	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
     happens         }




56
Closure shared variables
                                                                var assigned in the closure:
                                                                « shared closure variable »

     Impossible to   @TypeChecked	
  test()	
  {
     ensure the      	
  	
  	
  	
  def	
  var	
  =	
  "abc"	
  	
  	
  	
  	
  	
  	
  
                     	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  Date()	
  }
     assignment
                     	
  	
  	
  	
  if	
  (random)	
  cl()
     really          	
  	
  	
  	
  var.toUpperCase()	
  	
  //	
  Not	
  OK!
     happens         }


                      Only methods of the most specific compatible
                      type (LUB) are allowed by the type checker
56
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!
            }




57
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

57
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



58
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
59
Static Compilation: disadvantages
     • But you loose:

       –Dynamic features
         • metaclass changes, categories, etc.


       –Dynamic method dispatch
         • although as close as possible to « dynamic » Groovy




60
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()
              }


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




62
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

63
Summary: Groovy 2.0 themes
     • Modularity

     • Embark the JDK 7 enhancements
       –Project Coin
       –Invoke Dynamic

     • Static aspects
       –Static type checking
       –Static compilation

64
Thank you!




                                        e
                               e  Laforg velopment
                  Gu illaum oovy De
                                r
                  Hea  d of G
                                                 om
                                        g mail.c
                               la forge@
                   Email: g glaforge            /glaforg
                                                         e
                   Tw   itter: @ ttp://gplus.to pot.com
                                   h            ps
                    Go   ogle+: /glaforge.ap
                     Blog   : http:/




65
Questions & Answers
     • Got questions, really?
                                Q&A




66
Image credits
      •   Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg
      •   Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg
      •   Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg
      •   Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg
      •   Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg
      •   Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg
      •   Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg
      •   Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg
      •   Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg
      •   Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg
      •   Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg
      •   Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg
      •   Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg




67

More Related Content

What's hot

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 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
 
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
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjugBrian 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
 
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
 
Postgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformPostgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformSungJae Yun
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automationLarry Nung
 
Filesystem Performance from a Database Perspective
Filesystem Performance from a Database PerspectiveFilesystem Performance from a Database Perspective
Filesystem Performance from a Database PerspectiveMark Wong
 
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
 

What's hot (20)

Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
 
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
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007
 
Advanced GAR
Advanced GARAdvanced GAR
Advanced GAR
 
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
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
 
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
 
Centos config
Centos configCentos config
Centos config
 
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
 
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
 
Postgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud PlatformPostgres-BDR with Google Cloud Platform
Postgres-BDR with Google Cloud Platform
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automation
 
Filesystem Performance from a Database Perspective
Filesystem Performance from a Database PerspectiveFilesystem Performance from a Database Perspective
Filesystem Performance from a Database Perspective
 
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)
 

More from Guillaume Laforge

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Guillaume Laforge
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Guillaume Laforge
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
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
 

More from Guillaume Laforge (19)

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
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
 

Recently uploaded

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
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
 
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
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????blackmambaettijean
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
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
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 

Recently uploaded (20)

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
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
 
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
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
What is Artificial Intelligence?????????
What is Artificial Intelligence?????????What is Artificial Intelligence?????????
What is Artificial Intelligence?????????
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
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)
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 

Groovy update at SpringOne2GX 2012

  • 1. What’s new in Groovy 2.0? Guillaume Laforge Groovy Project Manager SpringSource / VMware @glaforge © 2012 SpringOne 2GX. All rights reserved. Do not distribute without permission.
  • 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 2
  • 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 3
  • 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 4
  • 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) 5
  • 6. Command chains pull  request    on  github   6
  • 7. Command chains Alternation of method names pull  request    on  github   6
  • 8. Command chains Alternation of method names pull  request    on  github   and parameters (even named ones) 6
  • 9. Command chains pull  request    on  github   6
  • 10. Command chains Equivalent to:      (              ).    (            ) pull  request    on  github   6
  • 12. Command chains //  methods  with  multiple  arguments  (commas) 7
  • 13. Command chains //  methods  with  multiple  arguments  (commas) take  coffee    with  sugar,  milk    and  liquor 7
  • 14. Command chains //  methods  with  multiple  arguments  (commas) take  coffee    with  sugar,  milk    and  liquor //  leverage  named-­‐args  as  punctuation 7
  • 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 7
  • 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 7
  • 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  {} 7
  • 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 7
  • 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 7
  • 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 7
  • 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 7
  • 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 7
  • 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 7
  • 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 7
  • 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 7
  • 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        (  ). 7
  • 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/ 8
  • 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 9
  • 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) 10
  • 30. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface  Invariant  {                Class  value()  //  a  closure  class }   Cont racts { @Invariant({  number  >=  0  }) class  Distance  {                float  number         Poor-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) 10
  • 32. Closure memoization def  plus  =  {  a,  b  -­‐>  sleep  1000;  a  +  b  }.memoize() 11
  • 33. Closure memoization def  plus  =  {  a,  b  -­‐>  sleep  1000;  a  +  b  }.memoize() assert  plus(1,  2)  ==  3  //  after  1000ms 11
  • 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 11
  • 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 11
  • 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     11
  • 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       11
  • 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 11
  • 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) 11
  • 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)   11
  • 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 11
  • 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)   11
  • 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 11
  • 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) 11
  • 45. Builtin JSON support • Consuming • Producing • Pretty-printing 12
  • 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  } 13
  • 47. Builtin JSON support import  groovy.json.*     def  json  =  new  JsonBuilder()     json.person  {                name  "Guillaume"        age  35                pets  "Hector",  "Felix" }   println  json.toString() 14
  • 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()        } } 14
  • 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"                                ]                } } 15
  • 50. New AST transformations • @Log • Controlling execution – @ThreadInterrupt – @TimedInterrupt • @Field – @ConditionalInterrupt • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • @Canonical • @WithWriteLock – @ToString – @EqualsAndHashCode – @TupleConstructor • @ListenerList 16
  • 51. @Log • Four different loggers can be injected –@Log import  groovy.util.logging.*   –@Commons   @Log –@Log4j class  Car  {         –@Slf4j        Car()  {                                log.info  'Car  constructed'                } • Possible to implement }     your own strategy def  c  =  new  Car() 17
  • 52. @Log • Four different loggers can be injected –@Log import  groovy.util.logging.*   –@Commons   @Log –@Log4j Guarded class  Car  {         –@Slf4j w/ an if        Car()  {                                log.info  'Car  constructed'                } • Possible to implement }     your own strategy def  c  =  new  Car() 17
  • 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 18
  • 54. @ThreadInterrupt @ThreadInterrupt import  groovy.transform.ThreadInterrupt     while  (true)  {        //  eat  lots  of  CPU } 19
  • 55. @ThreadInterrupt @ThreadInterrupt import  groovy.transform.ThreadInterrupt     while  (true)  { {        if  (Thread.currentThread().isInterrupted())                throw  new  InterruptedException()        //  eat  lots  of  CPU } 19
  • 56. @ToString • Provides a default toString() method import  groovy.transform.ToString   to your types   @ToString • Available options class  Person  {         – includeNames, includeFields,        String  name         includeSuper, excludes        int  age }     println  new  Person(name:  'Pete',  age:  15) //  =>  Person(Pete,  15) 20
  • 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() 21
  • 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 22
  • 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)            } } 23
  • 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)            } } 23
  • 61. 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 24
  • 62. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers –ImportCustomizer –ASTTransformationCustomizer –SecureASTCustomizer • But you can implement your own 25
  • 63. 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  ")                             26
  • 65. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation 28
  • 66. Groovy 2.0 bird’s eye view A more modular Groovy 29
  • 67. 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. 30
  • 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 31
  • 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") 32
  • 70. Extension modules • Create your own module Same structure –contribute instance extension methods as Categories package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric") 32
  • 71. Extension modules • Create your own module –contribute class extension methods package  foo class  StaticStringExtension  {        static  hi(String  self)  {                "Hi!"        } } //  usage:  String.hi() 33
  • 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 34
  • 73. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation 35
  • 74. Groovy 2.0 bird’s eye view Java 7 Project Coin Invoke Dynamic 36
  • 75. Java 7 / JDK 7 • Project Coin and InvokeDynamic 37
  • 76. 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 38
  • 77. 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 39
  • 78. Multicatch • One block for multiple exception caught –rather than duplicating the block try  {        /*  ...  */ }  catch(IOException  |  NullPointerException  e)  {        /*  one  block  to  treat  2  exceptions  */ } 40
  • 79. 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 41
  • 80. Groovy 2.0 bird’s eye view A more Java 7 Static Type Project Coin Checking modular Invoke Static Groovy Dynamic Compilation 42
  • 81. Groovy 2.0 bird’s eye view Static Type Checking Static Compilation 43
  • 82. 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 44
  • 83. 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 } 45
  • 84. Typos in a variable or method import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()   Compilation        def  name  =  "Guillaume"        //  variable  naamme  is  undeclared errors!        println  naamme } 45
  • 85. 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()   Compilation        def  name  =  "Guillaume"        //  variable  naamme  is  undeclared errors!        println  naamme } 45
  • 86. 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' 46
  • 87. Wrong assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object() Compilation   errors! def  o  =  new  Object() int  x  =  o   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1' 46
  • 88. 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 } 47
  • 89. Wrong return types //  checks  if/else  branch  return  values @TypeChecked int  method()  {        if  (true)  {  'String'  } Compilation        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 } 47
  • 90. 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        } } 48
  • 91. 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() } 49
  • 92. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } 50
  • 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()        } } 50
  • 94. 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 50
  • 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] } 51
  • 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> 51
  • 97. 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> 51
  • 98. 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! } 52
  • 99. 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 53
  • 100. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } 54
  • 101. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Not allowed: metaClass property is dynamic 54
  • 102. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Method not Not allowed: recognized metaClass property is dynamic 54
  • 103. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {                it.toUpperCase()  //  Not  OK        } } • A « Groovy Enhancement Proposal » to address the issue 55
  • 104. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {  String  it  -­‐>                it.toUpperCase()  //  OK,  it’s  a  String        } } • A « Groovy Enhancement Proposal » to address the issue 55
  • 105. Closure shared variables @TypeChecked  test()  {        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  }        if  (random)  cl()        var.toUpperCase()    //  Not  OK! } 56
  • 106. 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! } 56
  • 107. Closure shared variables var assigned in the closure: « shared closure variable » Impossible to @TypeChecked  test()  { ensure the        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really        var.toUpperCase()    //  Not  OK! happens } 56
  • 108. Closure shared variables var assigned in the closure: « shared closure variable » Impossible to @TypeChecked  test()  { ensure the        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really        var.toUpperCase()    //  Not  OK! happens } Only methods of the most specific compatible type (LUB) are allowed by the type checker 56
  • 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! } 57
  • 110. 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 57
  • 111. 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 58
  • 112. 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 59
  • 113. Static Compilation: disadvantages • But you loose: –Dynamic features • metaclass changes, categories, etc. –Dynamic method dispatch • although as close as possible to « dynamic » Groovy 60
  • 114. 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() } 61
  • 115. 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) 62
  • 116. 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 63
  • 117. Summary: Groovy 2.0 themes • Modularity • Embark the JDK 7 enhancements –Project Coin –Invoke Dynamic • Static aspects –Static type checking –Static compilation 64
  • 118. Thank you! e e Laforg velopment Gu illaum oovy De r Hea d of G om g mail.c la forge@ Email: g glaforge /glaforg e Tw itter: @ ttp://gplus.to pot.com h ps Go ogle+: /glaforge.ap Blog : http:/ 65
  • 119. Questions & Answers • Got questions, really? Q&A 66
  • 120. Image credits • Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg • Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg • Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg • Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg • Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg • Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg • Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg • Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg • Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg • Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg • Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg • Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg 67