SlideShare a Scribd company logo
1 of 127
Download to read offline
Groovy 2.0
and beyond
Guillaume Laforge
Groovy Project Manager
SpringSource / VMware
@glaforge
Guillaume Laforge

 • Groovy Project Manager at VMware
  • Initiator of the Grails framework
  • Creator of the Gaelyk
 • Co-author of Groovy in Action
 • Follow me on...
  • My blog: http://glaforge.appspot.com
  • Twitter: @glaforge
  • Google+: http://gplus.to/glaforge
A blossoming
ECOSYSTEM
GVM
GVM
GVM
GROOVY
ENVIRONMENT
MANAGER
GVM: Groovy enVironment Manager

 • New kid in town!
  • http://gvmtool.net/ — @gvmtool
 • Manage parallel versions of various SDKs
 • Currently supports
  • Groovy, Grails, Griffon, Gradle,Vert.x
 • On Linux, MacOS, Cygwin, Solaris, FreeBSD
GROOVY
Groovy 2.0 bird’s eye view

             Java 7      Static Type
A more        Project
                         Checking
modular        Coin

Groovy Invoke                Static
                         Compilation
             Dynamic
Groovy 2.0 bird’s eye view



A more
modular
Groovy
Groovy Modularity

 • Groovy’s « all » JAR weighs in at 6 MB
 • Nobody needs everything
  • Template engine, Ant scripting, Swing UI building...
 • Provide a smaller core
  • and several smaller JARs per feature
 • Provide hooks for setting up DGM methods,
The new JARs

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

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

 • Create your own module
  • contribute instance extension methods

    package	
  foo

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

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

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

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

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

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

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

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

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

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

             Java 7      Static Type
A more        Project
                         Checking
modular        Coin

Groovy Invoke                Static
                         Compilation
             Dynamic
Groovy 2.0 bird’s eye view

             Java 7
              Project
               Coin

             Invoke
             Dynamic
Binary literals

 • We had decimal, octal and hexadecimal
   notations for number literals
 • We can now use binary representations too
         int	
  x	
  =	
  0b10101111
         assert	
  x	
  ==	
  175
         	
  
         byte	
  aByte	
  =	
  0b00100001
         assert	
  aByte	
  ==	
  33
         	
  
         int	
  anInt	
  =	
  0b1010000101000101
         assert	
  anInt	
  ==	
  41285
Underscore in literals

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

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

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

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

 • Groovy 2.0 supports JDK 7’s
   invokeDynamic
  •   compiler has a flag for compiling against JDK 7
  •   might use the invokeDynamic backport for < JDK 7
 • Benefits
  •    more runtime performance!
      • at least as fast as current « dynamic » Groovy
  •   in the long run, will allow us to get rid of code!
      • call site caching, thanks to MethodHandles
      • metaclass registry, thanks to ClassValues
      • will let the JIT inline calls more easily
Groovy 2.0 bird’s eye view

             Java 7      Static Type
A more        Project
                         Checking
modular        Coin

Groovy Invoke                Static
                         Compilation
             Dynamic
Groovy 2.0 bird’s eye view


                         Static Type
                         Checking
                             Static
                         Compilation
Static Type Checking
 • Goal: make the Groovy compiler « grumpy »!
  •   and throw compilation errors (not at runtime)
 • Not everybody needs dynamic features
   all the time
  •   think Java libraries scripting
 • Grumpy should...
  •   tell you about your method or variable typos
  •   complain if you call methods that don’t exist
  •   shout on assignments of wrong types
  •   infer the types of your variables
  •   figure out GDK methods
Typos in a variable or method


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


               import	
  groovy.transform.TypeChecked
               	
  
               void	
  method()	
  {}
               	
  
               @TypeChecked	
  test()	
  {
               	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
               	
  	
  	
  	
  metthhoood()
Compilation
               	
  
     errors!   	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
               	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
               	
  	
  	
  	
  println	
  naamme
               }
Typos in a variable or method
Annotation can be at
 class or method level
                import	
  groovy.transform.TypeChecked
                	
  
                void	
  method()	
  {}
                	
  
                @TypeChecked	
  test()	
  {
                	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
                	
  	
  	
  	
  metthhoood()
Compilation
                	
  
     errors!    	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
                	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
                	
  	
  	
  	
  println	
  naamme
                }
Wrong assignments

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

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

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

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

     @TypeChecked	
  test()	
  {
     	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
     	
  
     	
  	
  	
  	
  //	
  String	
  type	
  infered	
  (even	
  inside	
  GString)
     	
  	
  	
  	
  println	
  "NAME	
  =	
  ${name.toUpperCase()}"	
  
     	
  
     	
  	
  	
  	
  //	
  Groovy	
  GDK	
  method	
  support
     	
  	
  	
  	
  //	
  (GDK	
  operator	
  overloading	
  too)
     	
  	
  	
  	
  println	
  name.trim()
     	
  
     	
  	
  	
  	
  int[]	
  numbers	
  =	
  [1,	
  2,	
  3]
     	
  	
  	
  	
  //	
  Element	
  n	
  is	
  an	
  int
     	
  	
  	
  	
  for	
  (int	
  n	
  in	
  numbers)	
  {
     	
  	
  	
  	
  	
  	
  	
  	
  println	
  n
     	
  	
  	
  	
  }
     }
Statically checked & dynamic methods

       @TypeChecked
       String	
  greeting(String	
  name)	
  {
       	
  	
  	
  	
  //	
  call	
  method	
  with	
  dynamic	
  behavior
       	
  	
  	
  	
  //	
  but	
  with	
  proper	
  signature
       	
  	
  	
  	
  generateMarkup(name.toUpperCase())
       }
       	
  
       //	
  usual	
  dynamic	
  behavior
       String	
  generateMarkup(String	
  name)	
  {
       	
  	
  	
  	
  def	
  sw	
  =	
  new	
  StringWriter()
       	
  	
  	
  	
  new	
  MarkupBuilder(sw).html	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  body	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  div	
  name
       	
  	
  	
  	
  	
  	
  	
  	
  }
       	
  	
  	
  	
  }
       	
  	
  	
  	
  sw.toString()
       }
Instanceof checks
 @TypeChecked	
  
 void	
  test(Object	
  val)	
  {

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


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

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

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


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

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


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

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

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

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

 • Type checking works at compile-time
  • adding @TypeChecked doesn’t change behavior
   • do not confuse with static compilation
 • Most dynamic features cannot be type checked
  • metaclass changes, categories
  • dynamically bound variables (ex: script’s binding)
 • But compile-time metaprogramming works
  • as long as proper type information is defined
Gotcha: runtime metaprogramming

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

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


                               Not allowed:
                            metaClass property
                               is dynamic
Gotcha: runtime metaprogramming

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


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


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


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


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

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

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

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



       Only methods of the most specific compatible
        type (LUB) are allowed by the type checker
Closure shared variables

      class	
  A	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {	
  void	
  foo()	
  {}	
  }
      class	
  B	
  extends	
  A	
  {	
  void	
  bar()	
  {}	
  }

      @TypeChecked	
  test()	
  {
      	
  	
  	
  	
  def	
  var	
  =	
  new	
  A()
      	
  	
  	
  	
  def	
  cl	
  =	
  {	
  var	
  =	
  new	
  B()	
  }
      	
  	
  	
  	
  if	
  (random)	
  cl()
      	
  	
  	
  	
  var.foo()	
  	
  	
  //	
  OK!
      }
Closure shared variables

      class	
  A	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  {	
  void	
  foo()	
  {}	
  }
      class	
  B	
  extends	
  A	
  {	
  void	
  bar()	
  {}	
  }

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


               var is at least an
                instance of A
Static Compilation

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

  • ie. generate the same byte code as javac
 • Also interesting for those stuck in JDK < 7
   to benefit from performance improvements
Static Compilation: advantages

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

 • But you loose:
  • Dynamic features
   • metaclass changes, categories, etc.
  • Dynamic method dispatch
   • although as close as possible to « dynamic » Groovy
Statically compiled & dynamic methods
       @CompileStatic
       String	
  greeting(String	
  name)	
  {
       	
  	
  	
  	
  //	
  call	
  method	
  with	
  dynamic	
  behavior
       	
  	
  	
  	
  //	
  but	
  with	
  proper	
  signature
       	
  	
  	
  	
  generateMarkup(name.toUpperCase())
       }
       	
  
       //	
  usual	
  dynamic	
  behavior
       String	
  generateMarkup(String	
  name)	
  {
       	
  	
  	
  	
  def	
  sw	
  =	
  new	
  StringWriter()
       	
  	
  	
  	
  new	
  MarkupBuilder(sw).html	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  body	
  {
       	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  div	
  name
       	
  	
  	
  	
  	
  	
  	
  	
  }
       	
  	
  	
  	
  }
       	
  	
  	
  	
  sw.toString()
       }
What about performance?
 • Comparisons between:
  •   Java


  •   Groovy static compilation (Groovy 2.0)
  •   Groovy with primitive optimizations (Groovy 1.8+)
  •   Groovy without optimizations (Groovy 1.7)
What about performance?

                                             Pi (π)     Binary
                                 Fibonacci
                                           quadrature   trees
                     Java        191 ms      97 ms      3.6 s
   1.7 1.8 2.0




                   Static
                 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
Back to the future...
Full invoke dynamic support                     Groovy
                                                 2.1
 • In Groovy 2.0, not all call paths
     were going through invoke dynamic calls
  • essentially method calls only
  • still used call site caching techniques
 • On JDK 7 with the « indy » JAR,
     Groovy 2.1 uses invoke dynamic
     everywhere
 •   On JDK < 7, still uses call site caching
@DelegatesTo                                  Groovy
                                               2.1
 • Static type checking works nicely
   for certain Domain-Specific Languages
  • command chains, extension methods, etc.
 • But for changes of delegation within closures,
   it’s not helping
  • often used by DSLs like within Gradle
 • Enters @DelegatesTo!
@DelegatesTo                    Groovy
                                 2.1
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
@DelegatesTo                                         Groovy
                                                      2.1
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}

void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
@DelegatesTo                                         Groovy
                                                      2.1
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}

void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}


exec(spec)	
  {
	
  	
  	
  	
  foo()
}
@DelegatesTo                                          Groovy
                                                       2.1
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}

void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}


exec(spec)	
  {                 Static type checker
	
  	
  	
  	
  foo()           doesn’t know about
}                               that foo() method
@DelegatesTo                                         Groovy
                                                      2.1




void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
@DelegatesTo                                         Groovy
                                                      2.1

                             Annotate with:
                             @DelegatesTo(ExecSpec)

void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
@DelegatesTo                                            Groovy
                                                              2.1
 • With a special delegation strategy


   void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
   	
  	
  	
  	
  c.delegate	
  =	
  sp
   	
  	
  	
  	
  c.resolveStrategy	
  =	
  DELEGATE_FIRST
   	
  	
  	
  	
  c()
   }
@DelegatesTo                                            Groovy
                                                              2.1
 • With a special delegation strategy
        Annotate with:
        @DelegatesTo(value = ExecSpec,
                  strategy = DELEGATE_FIRST)

   void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
   	
  	
  	
  	
  c.delegate	
  =	
  sp
   	
  	
  	
  	
  c.resolveStrategy	
  =	
  DELEGATE_FIRST
   	
  	
  	
  	
  c()
   }
@DelegatesTo                                             Groovy
                                                          2.1
 • Use Target to specify the precise
   argument to delegate to




    void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
    	
  	
  	
  	
  c.delegate	
  =	
  sp
    	
  	
  	
  	
  c()
    }
@DelegatesTo                                              Groovy
                                                           2.1
  • Use Target to specify the precise
    argument to delegate to

@DelegatesTo.Target("id")


     void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
     	
  	
  	
  	
  c.delegate	
  =	
  sp
     	
  	
  	
  	
  c()
     }
@DelegatesTo                                              Groovy
                                                           2.1
  • Use Target to specify the precise
    argument to delegate to

@DelegatesTo.Target("id")         @DelegatesTo(target = "id")


     void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
     	
  	
  	
  	
  c.delegate	
  =	
  sp
     	
  	
  	
  	
  c()
     }
@DelegatesTo                                   Groovy
                                                2.1
 • For DSLs using Groovy closure delegation
 • Great for...
  • documenting APIs
  • IDE integration
   • code completion, code navigation...
  • working nicely with static type checking
    and static compilation
Custom type checking                                                        Groovy
                                                                                2.1
 • You can make Groovy’s static type checking
   even smarter, with your own smarts!
  • even smarter than Java’s :-)
 • Create your own type checker extension
    @TypeChecked(extensions	
  =	
  
    	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'MyExtension.groovy')
    void	
  exec()	
  {
    	
  	
  	
  	
  //	
  code	
  to	
  be	
  further	
  checked...
    }
Custom type checking                       Groovy
                                             2.1
• Your own extension has access
  to an event-based API

  • onMethodSelection     • methodNotFound
  • afterMethodCall       • unresolvedVariable
  • beforeMethodCall      • unresolvedProperty
                          • unresolvedAttribute
  • afterVisitMethod
  • beforeVisitMethod     • incompatibleAssignment
Custom type checking                                                               Groovy
                                                                                       2.1

    MyExtension.groovy

 onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
 afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
 unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }
Custom type checking                                                               Groovy
                                                                                       2.1

    MyExtension.groovy

 onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
 afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
 unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }



                                                           Know your
                                                           Groovy AST
                                                           API well ;-)
Custom type checking                                                               Groovy
                                                                                       2.1

                                                                Doesn’t need
    MyExtension.groovy                                         to be compiled
 onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
 afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
 unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
 incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }



                                                           Know your
                                                           Groovy AST
                                                           API well ;-)
Alias annotations                         Groovy
                                              2.1


 • Ability to create meta-annotations
   combining and/or parameterizing
   other annotations


 • Works also for local AST transformations
   and their annotations
Alias annotations                       Groovy
                                         2.1
  @Immutable
  @ToString(excludes	
  =	
  ["age"])
  @AnnotationCollector
  @interface	
  MyAlias	
  {}
Alias annotations                               Groovy
                                                   2.1
  @Immutable
  @ToString(excludes	
  =	
  ["age"])
  @AnnotationCollector
  @interface	
  MyAlias	
  {}           The « collector »
Alias annotations                               Groovy
                                                   2.1
                                        Collected
  @Immutable
  @ToString(excludes	
  =	
  ["age"])   annotations
  @AnnotationCollector
  @interface	
  MyAlias	
  {}           The « collector »
Alias annotations                               Groovy
                                                   2.1
                                        Collected
  @Immutable
  @ToString(excludes	
  =	
  ["age"])   annotations
  @AnnotationCollector
  @interface	
  MyAlias	
  {}           The « collector »


 Your own custom
   alias name
Alias annotations                                        Groovy
                                                             2.1
                                             Collected
  @Immutable
  @ToString(excludes	
  =	
  ["age"])        annotations
  @AnnotationCollector
  @interface	
  MyAlias	
  {}               The « collector »


 Your own custom
   alias name                     @MyAlias
                                  class	
  Foo	
  {
                                  	
  	
  	
  	
  String	
  name
                                  	
  	
  	
  	
  int	
  age
                                  }
Alias annotations                                        Groovy
                                                             2.1
                                             Collected
  @Immutable
  @ToString(excludes	
  =	
  ["age"])        annotations
  @AnnotationCollector
  @interface	
  MyAlias	
  {}               The « collector »


 Your own custom
   alias name                     @MyAlias
                                  class	
  Foo	
  {
              Use your            	
  	
  	
  	
  String	
  name
            concise alias         	
  	
  	
  	
  int	
  age
                                  }
Take control of your Groovy!                     Groovy
                                                  2.1
 • Groovy 1.8 introduced compilation customizers
  • add imports, AST xforms, secure the AST...
 • With static type checking and static
   compilation, we received feedback from people
   wanting them applied « by default »


 • Allow to instruct the groovyc compiler
   with a configuration script
  • groovyc -configurator compConf.groovy Foo.groovy
Take control of your Groovy!                            Groovy
                                                           2.1
 • Add a default @ToString transform
  import	
  groovy.transform.ToString
  import	
  org.codehaus.groovy.control.customizers

 •	
  	
  	
  	
  	
  	
  	
  .ASTTransformationCustomizer

  config.addCompilationCustomizer(
  	
  	
  	
  	
  new	
  ASTTransformationCustomizer(ToString)
  )
Take control of your Groovy!                            Groovy
                                                           2.1
 • Add a default @ToString transform
  import	
  groovy.transform.ToString
  import	
  org.codehaus.groovy.control.customizers

 •	
  	
  	
  	
  	
  	
  	
  .ASTTransformationCustomizer

  config.addCompilationCustomizer(
  	
  	
  	
  	
  new	
  ASTTransformationCustomizer(ToString)
  )

       Implicit «config» variable representing
       a CompilationConfiguration instance
Take control of your Groovy!                          Groovy
                                                       2.1
 • You can use a builder syntax:
 config.customizers	
  {
 	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
 	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
 	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
 	
  	
  	
  	
  }
 }
Take control of your Groovy!                                     Groovy
                                                                  2.1
 • You can use a builder syntax:
 config.customizers	
  {
 	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
         config.customizers	
  {
 	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
         	
  	
  	
  	
  //	
  apply	
  to	
  *.gbean	
  files
 	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
         	
  	
  	
  	
  source(extension:	
  '.gbean')	
  {
 	
  	
  	
  	
  }
         	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
 }
         	
  	
  	
  	
  }
         }
Take control of your Groovy!                                                     Groovy
                                                                                     2.1
 • You can use a builder syntax:
 config.customizers	
  {
 	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
         config.customizers	
  {
 	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
         	
  	
  	
  	
  //	
  apply	
  to	
  *.gbean	
  files
 	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
                   config.customizers	
  {
         	
  	
  	
  	
  source(extension:	
  '.gbean')	
  {
 	
  	
  	
  	
  } 	
  	
  	
  	
  //	
  custom	
  filter	
  logic	
  
         	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
 }                 	
  	
  	
  	
  //	
  with	
  compilation	
  units
         	
  	
  	
  	
  }
         }         	
  	
  	
  	
  source(unitValidator:	
  {	
  unit	
  -­‐>	
  ...	
  })	
  {
                   	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
                   	
  	
  	
  	
  }
                   }
Roadmap


         Groovy 2.1                Groovy 4.0


     2012             2013         2014
                                   2014

  Groovy 2.0          Groovy 3.0
Roadmap


         Groovy 2.1                Groovy 4.0


     2012             2013         2014
                                   2014

  Groovy 2.0          Groovy 3.0
Roadmap


         Groovy 2.1                Groovy 4.0


     2012             2013         2014
                                   2014

  Groovy 2.0          Groovy 3.0
End of 2012... and the world?



2012
GGeX
      End of
    the world
End of 2012... and the world?



2012 Dec
GGeX 17-23
      End of
    the world
End of 2012... and the world?


   Groovy 2.1 beta

2012 Dec
GGeX 17-23
       End of
     the world
End of 2012... and the world?


   Groovy 2.1 beta

2012 Dec
GGeX 17-23
       End of        Recovering
     the world       from GGeX
End of 2012... and the world?


   Groovy 2.1 beta

2012 Dec
GGeX 17-23
       End of        Recovering
     the world       from GGeX
End of 2012... and the world?


   Groovy 2.1 beta       Christmas

2012 Dec
GGeX 17-23
       End of        Recovering
     the world       from GGeX
End of 2012... and the world?


   Groovy 2.1 beta       Christmas

2012 Dec
GGeX 17-23
       End of        Recovering
     the world       from GGeX
End of 2012... and the world?


   Groovy 2.1 beta       Christmas

2012 Dec
GGeX 17-23
       End of        Recovering
     the world       from GGeX
End of 2012... and the world?


   Groovy 2.1 beta       Christmas

2012 Dec
GGeX 17-23
       End of        Recovering      Recovering
     the world       from GGeX         again !
Happy New Year!



    Jan
    7-13
Happy New Year!


   Groovy 2.1 RC

    Jan
    7-13
Happy New Year!


   Groovy 2.1 RC

    Jan   Jan
    7-13 14-21
Happy New Year!


   Groovy 2.1 RC

    Jan   Jan
    7-13 14-21
                   Wait for
                   feedback
Happy New Year!


   Groovy 2.1 RC         Potential 2nd RC

    Jan   Jan
    7-13 14-21
                   Wait for
                   feedback
Happy New Year!


   Groovy 2.1 RC         Potential 2nd RC

    Jan   Jan                        Jan
    7-13 14-21                      22-29
                   Wait for
                   feedback
Happy New Year!


   Groovy 2.1 RC         Potential 2nd RC

    Jan   Jan                        Jan
    7-13 14-21                      22-29
                   Wait for             Groovy 2.1
                   feedback               Final !
Back to 2013 and beyond


          Groovy 2.1                Groovy 4.0


      2012             2013         2014
                                    2014

   Groovy 2.0          Groovy 3.0
Groovy
The infamous    3.0


MOP
  2
Groovy
           4.0




Antlr 4
grammar
oovy




          λ
          Gr



JDK
           4.0




 8
Lambdas
Summary (1/2)

 • As always, a rich and blossoming ecosystem
 • Groovy 2.0
  • more modularity
  • static theme
   • static type checking
   • static compilation
  • JDK 7 theme
   • invoke dynamic support
   • project coin syntax enhancements
Summary (2/2)

 • Groovy 2.1
  • complete indy support
  • @DelegatesTo
  • custom type checking for your DSLs
  • alias annotation
 • And beyond...
  • a new MOP (Meta-Object Protocol)
  • a new grammar with Antlr 4
  • JDK 8 lambda support
Thank you!



                                 ge
                      me   Lafor lopment
             Guillau roovy Deve
                      G
             H ead of                    m
                             @g  mail.co
                      laforge rge
              Email: g @glafo            /glaforg
                                                 e
                       :              .to
               Twitter : http://gplus spot.com
                         +             pp
                Google p://glaforge.a
                        tt
                Blog: h
Picture credits
 •   London
     http://www.londonup.com/media/1251/Tower-Bridge-london-582331_1024_768.jpg
 •   cherry blossom
     http://wallpaperswide.com/cherry_blossom_3-wallpapers.html
 •   NKOTB
     http://images1.fanpop.com/images/photos/2300000/nkotb-new-kids-on-the-block-2314664-1280-960.jpg
 •   USA today
     http://www.adams-pr.com/images/uploads/USA_Today_logo.jpg
 •   back to the future
     http://davidhiggerson.files.wordpress.com/2012/02/back-to-the-future-delorean.jpg
 •   magnifying glass
     http://www.renders-graphiques.fr/image/upload/normal/loupe.png
 •   Santa Claus
     http://icons.iconarchive.com/icons/fasticon/santa-claus/256/Happy-SantaClaus-icon.png
 •   Champagne
     http://reallife101blogs.files.wordpress.com/2010/11/champagne_glasses2.jpg
 •   that’s all folks
     http://4.bp.blogspot.com/-wJxosualm48/T4M_spcUUjI/AAAAAAAAB8E/njfLjNZQdsc/s1600/thats-all-folks.jpg
 •   MOP
     http://imagethumbnails.milo.com/024/913/894/trimmed/24913521_25989894_trimmed.jpg
 •   grammar
     http://edudemic.com/wp-content/uploads/2012/11/connected-learner-grammar.jpg

More Related Content

What's hot

Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseAndrew Eisenberg
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentationManav Prasad
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Victor_Cr
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Jaroslaw Palka
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionsaber tabatabaee
 
AST Transformations
AST TransformationsAST Transformations
AST TransformationsHamletDRC
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Latest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersLatest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersDaisyWatson5
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahNick Plante
 
Objective c runtime
Objective c runtimeObjective c runtime
Objective c runtimeInferis
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-CollectionsMohammad Shaker
 

What's hot (20)

Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
Groovy presentation
Groovy presentationGroovy presentation
Groovy presentation
 
Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"Club of anonimous developers "Refactoring: Legacy code"
Club of anonimous developers "Refactoring: Legacy code"
 
Google Dart
Google DartGoogle Dart
Google Dart
 
Clean code
Clean codeClean code
Clean code
 
Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014Patterns for JVM languages - Geecon 2014
Patterns for JVM languages - Geecon 2014
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 
Clean code
Clean codeClean code
Clean code
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Latest C++ Interview Questions and Answers
Latest C++ Interview Questions and AnswersLatest C++ Interview Questions and Answers
Latest C++ Interview Questions and Answers
 
From dot net_to_rails
From dot net_to_railsFrom dot net_to_rails
From dot net_to_rails
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Test Engine
Test EngineTest Engine
Test Engine
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
Objective c runtime
Objective c runtimeObjective c runtime
Objective c runtime
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-Collections
 
Unit testing concurrent code
Unit testing concurrent codeUnit testing concurrent code
Unit testing concurrent code
 

Similar to Groovy 2 and beyond

Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouAndres Almiray
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneAndres Almiray
 
Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailszenMonkey
 
Lecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLê Thưởng
 
Introduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transformsIntroduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transformsMarcin Grzejszczak
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
Infinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on androidInfinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on androidInfinum
 
Ruby programming introduction
Ruby programming introductionRuby programming introduction
Ruby programming introductionASIT Education
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?Nikita Popov
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Fwdays
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy PluginsPaul King
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyAli Tanwir
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8confGR8Conf
 
Core Java Concepts
Core Java ConceptsCore Java Concepts
Core Java Conceptsmdfkhan625
 
Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts S Akai
 
Learn Ruby Programming in Amc Square Learning
Learn Ruby Programming in Amc Square LearningLearn Ruby Programming in Amc Square Learning
Learn Ruby Programming in Amc Square LearningASIT Education
 

Similar to Groovy 2 and beyond (20)

Apache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and YouApache Groovy's Metaprogramming Options and You
Apache Groovy's Metaprogramming Options and You
 
Oscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast LaneOscon Java Testing on the Fast Lane
Oscon Java Testing on the Fast Lane
 
Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And Grails
 
Lecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdfLecture 03 - JQuery.pdf
Lecture 03 - JQuery.pdf
 
Introduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transformsIntroduction to Groovy runtime metaprogramming and AST transforms
Introduction to Groovy runtime metaprogramming and AST transforms
 
Test Driven In Groovy
Test Driven In GroovyTest Driven In Groovy
Test Driven In Groovy
 
Groovy!
Groovy!Groovy!
Groovy!
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
Infinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on androidInfinum android talks_10_getting groovy on android
Infinum android talks_10_getting groovy on android
 
Ruby programming introduction
Ruby programming introductionRuby programming introduction
Ruby programming introduction
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
 
Grooscript greach 2015
Grooscript greach 2015Grooscript greach 2015
Grooscript greach 2015
 
Atlassian Groovy Plugins
Atlassian Groovy PluginsAtlassian Groovy Plugins
Atlassian Groovy Plugins
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
MetaProgramming with Groovy
MetaProgramming with GroovyMetaProgramming with Groovy
MetaProgramming with Groovy
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 
Core Java Concepts
Core Java ConceptsCore Java Concepts
Core Java Concepts
 
Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts
 
Learn Ruby Programming in Amc Square Learning
Learn Ruby Programming in Amc Square LearningLearn Ruby Programming in Amc Square Learning
Learn Ruby Programming in Amc Square Learning
 

More from Guillaume 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 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Guillaume 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
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Guillaume Laforge
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Guillaume Laforge
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Guillaume Laforge
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGuillaume 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
 
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, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Guillaume 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
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Guillaume 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 Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Guillaume 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 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
 

More from Guillaume Laforge (20)

Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
 
JavaOne 2012 Groovy update
JavaOne 2012 Groovy updateJavaOne 2012 Groovy update
JavaOne 2012 Groovy update
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume 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 Languages
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
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 Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
 
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
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - 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...
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 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
 

Recently uploaded

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
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
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
 
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
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
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
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
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
 
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
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 

Recently uploaded (20)

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
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
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)
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
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
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
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
 
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
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 

Groovy 2 and beyond

  • 1. Groovy 2.0 and beyond Guillaume Laforge Groovy Project Manager SpringSource / VMware @glaforge
  • 2. Guillaume Laforge • Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk • Co-author of Groovy in Action • Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge
  • 4.
  • 5.
  • 6.
  • 7.
  • 8. GVM
  • 9.
  • 10. GVM
  • 12. GVM: Groovy enVironment Manager • New kid in town! • http://gvmtool.net/ — @gvmtool • Manage parallel versions of various SDKs • Currently supports • Groovy, Grails, Griffon, Gradle,Vert.x • On Linux, MacOS, Cygwin, Solaris, FreeBSD
  • 14. Groovy 2.0 bird’s eye view Java 7 Static Type A more Project Checking modular Coin Groovy Invoke Static Compilation Dynamic
  • 15. Groovy 2.0 bird’s eye view A more modular Groovy
  • 16. 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,
  • 17. 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
  • 18. 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
  • 19. 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")
  • 20. Extension modules • Create your own module • contribute instance extension methods Same structure as Categories package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric")
  • 21. Extension modules • Create your own module • contribute class extension methods package  foo class  StaticStringExtension  {        static  hi(String  self)  {                "Hi!"        } } //  usage:  String.hi()
  • 22. 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
  • 23. Groovy 2.0 bird’s eye view Java 7 Static Type A more Project Checking modular Coin Groovy Invoke Static Compilation Dynamic
  • 24. Groovy 2.0 bird’s eye view Java 7 Project Coin Invoke Dynamic
  • 25. Binary literals • We had decimal, octal and hexadecimal notations for number literals • We can now use binary representations too int  x  =  0b10101111 assert  x  ==  175   byte  aByte  =  0b00100001 assert  aByte  ==  33   int  anInt  =  0b1010000101000101 assert  anInt  ==  41285
  • 26. 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
  • 27. Multicatch • One block for multiple exception caught • rather than duplicating the block try  {        /*  ...  */ }  catch(IOException  |  NullPointerException  e)  {        /*  one  block  to  treat  2  exceptions  */ }
  • 28. 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
  • 29. Groovy 2.0 bird’s eye view Java 7 Static Type A more Project Checking modular Coin Groovy Invoke Static Compilation Dynamic
  • 30. Groovy 2.0 bird’s eye view Static Type Checking Static Compilation
  • 31. 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
  • 32. 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 }
  • 33. Typos in a variable or method import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood() Compilation   errors!        def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme }
  • 34. Typos in a variable or method Annotation can be at class or method level import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood() Compilation   errors!        def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme }
  • 35. 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'
  • 36. Wrong assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object() Compilation   def  o  =  new  Object() errors! int  x  =  o   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1'
  • 37. 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 }
  • 38. Wrong return types //  checks  if/else  branch  return  values @TypeChecked int  method()  { Compilation        if  (true)  {  'String'  } error!        else  {  42  } } //  works  for  switch/case  &  try/catch/finally   //  transparent  toString()  implied @TypeChecked String  greeting(String  name)  {        def  sb  =  new  StringBuilder()        sb  <<  "Hi  "  <<  name }
  • 39. 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        } }
  • 40. 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() }
  • 41. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } }
  • 42. Instanceof checks @TypeChecked   void  test(Object  val)  { No need        if  (val  instanceof  String)  {                println  val.toUpperCase() for casts        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } }
  • 43. Instanceof checks @TypeChecked   void  test(Object  val)  { No need        if  (val  instanceof  String)  {                println  val.toUpperCase() for casts        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } Can call String#multiply(int) from the Groovy Development Kit
  • 44. 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] }
  • 45. 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>
  • 46. 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>
  • 47. 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! }
  • 48. 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) • But compile-time metaprogramming works • as long as proper type information is defined
  • 49. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() }
  • 50. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Not allowed: metaClass property is dynamic
  • 51. Gotcha: runtime metaprogramming @TypeChecked   void  test()  {        Integer.metaClass.foo  =  {}        123.foo() } Method not Not allowed: recognized metaClass property is dynamic
  • 52. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {                it.toUpperCase()  //  Not  OK        } }
  • 53. Gotcha: explicit type for closures @TypeChecked  test()  {        ["a",  "b",  "c"].collect  {  String  it  -­‐>                it.toUpperCase()  //  OK,  it’s  a  String        } }
  • 54. Closure shared variables @TypeChecked  test()  {        def  var  =  "abc"                      def  cl  =  {  var  =  new  Date()  }        if  (random)  cl()        var.toUpperCase()    //  Not  OK! }
  • 55. 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 » @TypeChecked  test()  { Impossible to        def  var  =  "abc"               ensure the        def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really happens        var.toUpperCase()    //  Not  OK! }
  • 57. Closure shared variables var assigned in the closure: « shared closure variable » @TypeChecked  test()  { Impossible to        def  var  =  "abc"               ensure the        def  cl  =  {  var  =  new  Date()  } assignment        if  (random)  cl() really happens        var.toUpperCase()    //  Not  OK! } Only methods of the most specific compatible type (LUB) are allowed by the type checker
  • 58. Closure shared variables class  A                      {  void  foo()  {}  } class  B  extends  A  {  void  bar()  {}  } @TypeChecked  test()  {        def  var  =  new  A()        def  cl  =  {  var  =  new  B()  }        if  (random)  cl()        var.foo()      //  OK! }
  • 59. Closure shared variables class  A                      {  void  foo()  {}  } class  B  extends  A  {  void  bar()  {}  } @TypeChecked  test()  {        def  var  =  new  A()        def  cl  =  {  var  =  new  B()  }        if  (random)  cl()        var.foo()      //  OK! } var is at least an instance of A
  • 60. 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
  • 61. 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
  • 62. Static Compilation: disadvantages • But you loose: • Dynamic features • metaclass changes, categories, etc. • Dynamic method dispatch • although as close as possible to « dynamic » Groovy
  • 63. 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() }
  • 64. 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)
  • 65. What about performance? Pi (π) Binary Fibonacci quadrature trees Java 191 ms 97 ms 3.6 s 1.7 1.8 2.0 Static 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
  • 66.
  • 67. Back to the future...
  • 68. Full invoke dynamic support Groovy 2.1 • In Groovy 2.0, not all call paths were going through invoke dynamic calls • essentially method calls only • still used call site caching techniques • On JDK 7 with the « indy » JAR, Groovy 2.1 uses invoke dynamic everywhere • On JDK < 7, still uses call site caching
  • 69. @DelegatesTo Groovy 2.1 • Static type checking works nicely for certain Domain-Specific Languages • command chains, extension methods, etc. • But for changes of delegation within closures, it’s not helping • often used by DSLs like within Gradle • Enters @DelegatesTo!
  • 70. @DelegatesTo Groovy 2.1 class  ExecSpec  {        void  foo() }
  • 71. @DelegatesTo Groovy 2.1 class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 72. @DelegatesTo Groovy 2.1 class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  {        foo() }
  • 73. @DelegatesTo Groovy 2.1 class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  { Static type checker        foo() doesn’t know about } that foo() method
  • 74. @DelegatesTo Groovy 2.1 void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 75. @DelegatesTo Groovy 2.1 Annotate with: @DelegatesTo(ExecSpec) void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 76. @DelegatesTo Groovy 2.1 • With a special delegation strategy void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c.resolveStrategy  =  DELEGATE_FIRST        c() }
  • 77. @DelegatesTo Groovy 2.1 • With a special delegation strategy Annotate with: @DelegatesTo(value = ExecSpec, strategy = DELEGATE_FIRST) void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c.resolveStrategy  =  DELEGATE_FIRST        c() }
  • 78. @DelegatesTo Groovy 2.1 • Use Target to specify the precise argument to delegate to void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 79. @DelegatesTo Groovy 2.1 • Use Target to specify the precise argument to delegate to @DelegatesTo.Target("id") void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 80. @DelegatesTo Groovy 2.1 • Use Target to specify the precise argument to delegate to @DelegatesTo.Target("id") @DelegatesTo(target = "id") void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() }
  • 81. @DelegatesTo Groovy 2.1 • For DSLs using Groovy closure delegation • Great for... • documenting APIs • IDE integration • code completion, code navigation... • working nicely with static type checking and static compilation
  • 82. Custom type checking Groovy 2.1 • You can make Groovy’s static type checking even smarter, with your own smarts! • even smarter than Java’s :-) • Create your own type checker extension @TypeChecked(extensions  =                            'MyExtension.groovy') void  exec()  {        //  code  to  be  further  checked... }
  • 83. Custom type checking Groovy 2.1 • Your own extension has access to an event-based API • onMethodSelection • methodNotFound • afterMethodCall • unresolvedVariable • beforeMethodCall • unresolvedProperty • unresolvedAttribute • afterVisitMethod • beforeVisitMethod • incompatibleAssignment
  • 84. Custom type checking Groovy 2.1 MyExtension.groovy onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  }
  • 85. Custom type checking Groovy 2.1 MyExtension.groovy onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } Know your Groovy AST API well ;-)
  • 86. Custom type checking Groovy 2.1 Doesn’t need MyExtension.groovy to be compiled onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } Know your Groovy AST API well ;-)
  • 87. Alias annotations Groovy 2.1 • Ability to create meta-annotations combining and/or parameterizing other annotations • Works also for local AST transformations and their annotations
  • 88. Alias annotations Groovy 2.1 @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {}
  • 89. Alias annotations Groovy 2.1 @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} The « collector »
  • 90. Alias annotations Groovy 2.1 Collected @Immutable @ToString(excludes  =  ["age"]) annotations @AnnotationCollector @interface  MyAlias  {} The « collector »
  • 91. Alias annotations Groovy 2.1 Collected @Immutable @ToString(excludes  =  ["age"]) annotations @AnnotationCollector @interface  MyAlias  {} The « collector » Your own custom alias name
  • 92. Alias annotations Groovy 2.1 Collected @Immutable @ToString(excludes  =  ["age"]) annotations @AnnotationCollector @interface  MyAlias  {} The « collector » Your own custom alias name @MyAlias class  Foo  {        String  name        int  age }
  • 93. Alias annotations Groovy 2.1 Collected @Immutable @ToString(excludes  =  ["age"]) annotations @AnnotationCollector @interface  MyAlias  {} The « collector » Your own custom alias name @MyAlias class  Foo  { Use your        String  name concise alias        int  age }
  • 94. Take control of your Groovy! Groovy 2.1 • Groovy 1.8 introduced compilation customizers • add imports, AST xforms, secure the AST... • With static type checking and static compilation, we received feedback from people wanting them applied « by default » • Allow to instruct the groovyc compiler with a configuration script • groovyc -configurator compConf.groovy Foo.groovy
  • 95. Take control of your Groovy! Groovy 2.1 • Add a default @ToString transform import  groovy.transform.ToString import  org.codehaus.groovy.control.customizers •              .ASTTransformationCustomizer config.addCompilationCustomizer(        new  ASTTransformationCustomizer(ToString) )
  • 96. Take control of your Groovy! Groovy 2.1 • Add a default @ToString transform import  groovy.transform.ToString import  org.codehaus.groovy.control.customizers •              .ASTTransformationCustomizer config.addCompilationCustomizer(        new  ASTTransformationCustomizer(ToString) ) Implicit «config» variable representing a CompilationConfiguration instance
  • 97. Take control of your Groovy! Groovy 2.1 • You can use a builder syntax: config.customizers  {        //  apply  to  MyBean.groovy        source(basename:  'MyBean')  {                ast(ToString)        } }
  • 98. Take control of your Groovy! Groovy 2.1 • You can use a builder syntax: config.customizers  {        //  apply  to  MyBean.groovy config.customizers  {        source(basename:  'MyBean')  {        //  apply  to  *.gbean  files                ast(ToString)        source(extension:  '.gbean')  {        }                ast(ToString) }        } }
  • 99. Take control of your Groovy! Groovy 2.1 • You can use a builder syntax: config.customizers  {        //  apply  to  MyBean.groovy config.customizers  {        source(basename:  'MyBean')  {        //  apply  to  *.gbean  files                ast(ToString) config.customizers  {        source(extension:  '.gbean')  {        }        //  custom  filter  logic                  ast(ToString) }        //  with  compilation  units        } }        source(unitValidator:  {  unit  -­‐>  ...  })  {                ast(ToString)        } }
  • 100. Roadmap Groovy 2.1 Groovy 4.0 2012 2013 2014 2014 Groovy 2.0 Groovy 3.0
  • 101. Roadmap Groovy 2.1 Groovy 4.0 2012 2013 2014 2014 Groovy 2.0 Groovy 3.0
  • 102. Roadmap Groovy 2.1 Groovy 4.0 2012 2013 2014 2014 Groovy 2.0 Groovy 3.0
  • 103. End of 2012... and the world? 2012 GGeX End of the world
  • 104. End of 2012... and the world? 2012 Dec GGeX 17-23 End of the world
  • 105. End of 2012... and the world? Groovy 2.1 beta 2012 Dec GGeX 17-23 End of the world
  • 106. End of 2012... and the world? Groovy 2.1 beta 2012 Dec GGeX 17-23 End of Recovering the world from GGeX
  • 107. End of 2012... and the world? Groovy 2.1 beta 2012 Dec GGeX 17-23 End of Recovering the world from GGeX
  • 108. End of 2012... and the world? Groovy 2.1 beta Christmas 2012 Dec GGeX 17-23 End of Recovering the world from GGeX
  • 109. End of 2012... and the world? Groovy 2.1 beta Christmas 2012 Dec GGeX 17-23 End of Recovering the world from GGeX
  • 110. End of 2012... and the world? Groovy 2.1 beta Christmas 2012 Dec GGeX 17-23 End of Recovering the world from GGeX
  • 111. End of 2012... and the world? Groovy 2.1 beta Christmas 2012 Dec GGeX 17-23 End of Recovering Recovering the world from GGeX again !
  • 112. Happy New Year! Jan 7-13
  • 113. Happy New Year! Groovy 2.1 RC Jan 7-13
  • 114. Happy New Year! Groovy 2.1 RC Jan Jan 7-13 14-21
  • 115. Happy New Year! Groovy 2.1 RC Jan Jan 7-13 14-21 Wait for feedback
  • 116. Happy New Year! Groovy 2.1 RC Potential 2nd RC Jan Jan 7-13 14-21 Wait for feedback
  • 117. Happy New Year! Groovy 2.1 RC Potential 2nd RC Jan Jan Jan 7-13 14-21 22-29 Wait for feedback
  • 118. Happy New Year! Groovy 2.1 RC Potential 2nd RC Jan Jan Jan 7-13 14-21 22-29 Wait for Groovy 2.1 feedback Final !
  • 119. Back to 2013 and beyond Groovy 2.1 Groovy 4.0 2012 2013 2014 2014 Groovy 2.0 Groovy 3.0
  • 120. Groovy The infamous 3.0 MOP 2
  • 121. Groovy 4.0 Antlr 4 grammar
  • 122. oovy λ Gr JDK 4.0 8 Lambdas
  • 123.
  • 124. Summary (1/2) • As always, a rich and blossoming ecosystem • Groovy 2.0 • more modularity • static theme • static type checking • static compilation • JDK 7 theme • invoke dynamic support • project coin syntax enhancements
  • 125. Summary (2/2) • Groovy 2.1 • complete indy support • @DelegatesTo • custom type checking for your DSLs • alias annotation • And beyond... • a new MOP (Meta-Object Protocol) • a new grammar with Antlr 4 • JDK 8 lambda support
  • 126. Thank you! ge me Lafor lopment Guillau roovy Deve G H ead of m @g mail.co laforge rge Email: g @glafo /glaforg e : .to Twitter : http://gplus spot.com + pp Google p://glaforge.a tt Blog: h
  • 127. Picture credits • London http://www.londonup.com/media/1251/Tower-Bridge-london-582331_1024_768.jpg • cherry blossom http://wallpaperswide.com/cherry_blossom_3-wallpapers.html • NKOTB http://images1.fanpop.com/images/photos/2300000/nkotb-new-kids-on-the-block-2314664-1280-960.jpg • USA today http://www.adams-pr.com/images/uploads/USA_Today_logo.jpg • back to the future http://davidhiggerson.files.wordpress.com/2012/02/back-to-the-future-delorean.jpg • magnifying glass http://www.renders-graphiques.fr/image/upload/normal/loupe.png • Santa Claus http://icons.iconarchive.com/icons/fasticon/santa-claus/256/Happy-SantaClaus-icon.png • Champagne http://reallife101blogs.files.wordpress.com/2010/11/champagne_glasses2.jpg • that’s all folks http://4.bp.blogspot.com/-wJxosualm48/T4M_spcUUjI/AAAAAAAAB8E/njfLjNZQdsc/s1600/thats-all-folks.jpg • MOP http://imagethumbnails.milo.com/024/913/894/trimmed/24913521_25989894_trimmed.jpg • grammar http://edudemic.com/wp-content/uploads/2012/11/connected-learner-grammar.jpg