SlideShare une entreprise Scribd logo
1  sur  179
Télécharger pour lire hors ligne
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
GuillaumeLaforge
@glaforge 
Lift-offwithGroovy2
...andbeyond!
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
GuillaumeLaforge
@glaforge 
Lift-offwithGroovy2
...andbeyond!
GuillaumeLaforge
@glaforge 
http://glaforge.appspot.com 
http://gplus.to/glaforge 
GuillaumeLaforge
@glaforge 
http://glaforge.appspot.com 
http://gplus.to/glaforge 
Presentation will be uploaded to
https://speakerdeck.com/glaforge
A dynamic language,
optionally typed
Groovy
...statically type checked
and compiled as needed
Groovy
Syntax deriving from
Java, thus easy to learn
Groovy
million
downloads
in 2012
1.7
10
Ablossoming
Ecosystem
GVM
Let’s start the
engine
Modularity
Java 7: ProjectCoin & invokedynamic
Static typechecking & compilation
Modularity
« Not everybody needs everything,
all the time, at the same time! »
Groovy modularity
• The « groovy-all » weighted... 6 MB !
• In addition to the language, we have APIs:
– template engine,Ant task scripting, Swing UI builder,
JMX builder...
• We want a lighter « core »
– with APIs in the form of modules
• Ability to wire in « extension methods »
16
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console
– docgenerator
– groovydoc
– groovysh
– ant
– bsf
– jsr-223
– jmx
– sql
– swing
– servlet
– templates
– test
– testng
– json
– xml
17
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console
– docgenerator
– groovydoc
– groovysh
– ant
– bsf
– jsr-223
– jmx
– sql
– swing
– servlet
– templates
– test
– testng
– json
– xml
17
« Let’s go
shopping »
Extension modules
• Create your own extension module
– contribute instance methods
package	
  foo
class	
  StringExtension	
  {
	
  	
  	
  	
  static	
  introduces(String	
  self,	
  String	
  name)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "Hi	
  ${name),	
  I’m	
  ${self}"
	
  	
  	
  	
  }
}
//	
  usage:	
  "Guillaume".introduces("Cédric")
19
Extension modules
• Create your own extension module
– contribute instance methods
package	
  foo
class	
  StringExtension	
  {
	
  	
  	
  	
  static	
  introduces(String	
  self,	
  String	
  name)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "Hi	
  ${name),	
  I’m	
  ${self}"
	
  	
  	
  	
  }
}
//	
  usage:	
  "Guillaume".introduces("Cédric")
Same structure as
categories
19
Extension modules
• Create your own extension module
– contribute static methods
20
package	
  foo
class	
  StaticStringExtension	
  {
	
  	
  	
  	
  static	
  hi(String	
  self)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "Hi!"
	
  	
  	
  	
  }
}
//	
  usage:	
  String.hi()
Extension module descriptor
• META-INF/
– services/
•org.codehaus.groovy.runtime.ExtensionModule
moduleName	
  =	
  stringExtensions
moduleVersion	
  =	
  1.0
//	
  comma	
  separated	
  list	
  of	
  FQN	
  class	
  names
extensionClasses	
  =	
  foo.StringExtension
//	
  comma	
  separated	
  list	
  of	
  FQN	
  class	
  names
staticExtensionClasses	
  =	
  
foo.StaticStringExtension
21
Java 7
theme
« ProjectCoin » syntax
InvokeDynamic support
Binary literals
• In addition to decimal, octal and hexa
• A new binary representation:
int	
  x	
  =	
  0b10101111
assert	
  x	
  ==	
  175
	
  
byte	
  aByte	
  =	
  0b00100001
assert	
  aByte	
  ==	
  33
	
  
int	
  anInt	
  =	
  0b1010000101000101
assert	
  anInt	
  ==	
  41285
23
Underscores in literals
• Use underscores in number literals
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
25
Multi-catch exception blocks
• A single catch block to catch several exceptions
at once, rather than duplicating blocks
try	
  {
	
  	
  	
  	
  /*	
  ...	
  */
}	
  catch(IOException	
  |	
  NullPointerException	
  e)	
  {
	
  	
  	
  	
  /*	
  un	
  seul	
  bloc	
  */
}
26
Woot!
JDK 7 Invoke Dynamic support
• A « flag » to compile with « indy »
– we might propose a backport for JDK < 7
• Avantages
– more runtime performance
•well... in theory...
– In the long term, we might replace
•« call site caching » ➔ MethodHandles
•« metaclass registry » ➔ ClassValues
– and the JIT « inlines » code more easily
28
A « static »
theme
Static type checking
Static compilation
Static type checking
• Goal: make the compiler grumpy!
– throw errors at compile-time
•rather than at runtime
30
We don’t need
dynamic features
all the time!
We don’t need
dynamic features
all the time!
Nah !
Static type checking
• A « grumpy » compiler should...
– say when there’s a typo
in a method or variable name
– complain when a non-existent
method is called
– or on bad assignments
or use a bad return type
32
Static type checking
• The compiler should infer types...
– less explicit types and casts
– fine grained type inference
•« flow typing »
•« lowest upper bound »
33
Static type checking
• But the compiler should understand
extension methods
– allows a good level of dynamism,
despite the additional restrictions
34
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
	
  	
  	
  	
  metthhoood()
	
  
	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
	
  	
  	
  	
  println	
  naamme
}
35
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
	
  	
  	
  	
  metthhoood()
	
  
	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
	
  	
  	
  	
  println	
  naamme
}
Compilation
error
35
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
	
  	
  	
  	
  metthhoood()
	
  
	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
	
  	
  	
  	
  println	
  naamme
}
Compilation
error
Compilation
error
35
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  Cannot	
  find	
  matching	
  method	
  metthhoood()
	
  	
  	
  	
  metthhoood()
	
  
	
  	
  	
  	
  def	
  name	
  =	
  "Guillaume"
	
  	
  	
  	
  //	
  variable	
  naamme	
  is	
  undeclared
	
  	
  	
  	
  println	
  naamme
}
Compilation
error
Compilation
error
Annotation at the
method or class level
35
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  Object()
Set	
  set	
  =	
  new	
  Object()
	
  
String[]	
  strings	
  =	
  ['a','b','c']
int	
  str	
  =	
  strings[0]
	
  
//	
  cannot	
  find	
  matching	
  method	
  plus()
int	
  i	
  =	
  0
i	
  +=	
  '1'
36
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  Object()
Set	
  set	
  =	
  new	
  Object()
	
  
String[]	
  strings	
  =	
  ['a','b','c']
int	
  str	
  =	
  strings[0]
	
  
//	
  cannot	
  find	
  matching	
  method	
  plus()
int	
  i	
  =	
  0
i	
  +=	
  '1'
Compilation
error
36
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  Object()
Set	
  set	
  =	
  new	
  Object()
	
  
String[]	
  strings	
  =	
  ['a','b','c']
int	
  str	
  =	
  strings[0]
	
  
//	
  cannot	
  find	
  matching	
  method	
  plus()
int	
  i	
  =	
  0
i	
  +=	
  '1'
Compilation
error
Compilation
error
36
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  Object()
Set	
  set	
  =	
  new	
  Object()
	
  
String[]	
  strings	
  =	
  ['a','b','c']
int	
  str	
  =	
  strings[0]
	
  
//	
  cannot	
  find	
  matching	
  method	
  plus()
int	
  i	
  =	
  0
i	
  +=	
  '1'
Compilation
error
Compilation
error
Compilation
error
36
Wrong return type
//	
  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
}
37
Wrong return type
//	
  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
}
Compilation
error
37
Wrong return type
//	
  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
}
Compilation
error
In the end, call
StringBuilder’s toString()
37
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
	
  	
  	
  	
  }
}
38
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
	
  	
  	
  	
  }
}
Variable optionally typed
38
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
	
  	
  	
  	
  }
}
Variable optionally typed
Type String infered
38
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
	
  	
  	
  	
  }
}
Variable optionally typed
trim() method added
dynamically by Groovy
Type String infered
38
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
	
  	
  	
  	
  }
}
Variable optionally typed
Array element type inferred
trim() method added
dynamically by Groovy
Type String infered
38
Mix dynamic & statically checked code
@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()
}
39
Mix dynamic & statically checked code
@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()
}
Statically checked
39
Mix dynamic & statically checked code
@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()
}
Statically checked
Dynamic
39
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()
	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
	
  	
  	
  	
  }
}
40
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()
	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
	
  	
  	
  	
  }
}
No need
for casts
40
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()
	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
	
  	
  	
  	
  }
}
No need
for casts
No need
for casts
40
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  val.toUpperCase()
	
  	
  	
  	
  }	
  else	
  if	
  (val	
  instanceof	
  Number)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "X"	
  *	
  val.intValue()
	
  	
  	
  	
  }
}
No need
for casts
No need
for castsUnderstand GDK’s method:
String#multiply(int)
40
Lowest Upper Bound
• The smallest common « super » type
– might be virtual (« non-denotable »)
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  an	
  integer	
  and	
  a	
  BigDecimal
	
  	
  	
  	
  return	
  [1234,	
  3.14]
}
41
Lowest Upper Bound
• The smallest common « super » type
– might be virtual (« non-denotable »)
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  //	
  an	
  integer	
  and	
  a	
  BigDecimal
	
  	
  	
  	
  return	
  [1234,	
  3.14]
}
Infered type:
List<T extends Number & Comparable & Serializable>
41
Flow typing
• Static type checking « follows » the type of values
assigned into variables
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  var	
  =	
  123	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  int	
  infered
	
  	
  	
  	
  int	
  x	
  =	
  var	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  var	
  is	
  an	
  int
	
  	
  	
  	
  var	
  =	
  "123"	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  assign	
  a	
  String	
  into	
  var
	
  	
  	
  	
  x	
  =	
  var.toInteger()	
  	
  	
  //	
  no	
  cast	
  needed
	
  	
  	
  	
  var	
  =	
  123
	
  	
  	
  	
  x	
  =	
  var.toUpperCase()	
  //	
  error,	
  var	
  is	
  an	
  int	
  !
}
42
Not really clean,
your code!
Not really clean,
your code!
Grmmpf...no!
Static type checking and dynamic code
•Type checking happens at compile-time
– @TypeChecked doesn’t change behavior!
•do not confound with static compilation
• Most dynamic features can’t be checked
– metaclass changes, categories...
– dynamic variables from the « script binding »
• But compile-time metaprogramming OK
– if enough type information is available
44
But if it ain’t dynamic,
can we compile
it statically?
But if it ain’t dynamic,
can we compile
it statically?
But of course!!!
Static compilation
• Given the code is statically type checked,
lots of type information was infered...
so we can as well compile statically !
– ie. generate the same bytecode as javac
• Also interesting when stuck on JDK < 7
to gain performance improvements
46
Avantages of static compilation
• We gain:
– type safety
•thanks to static type checking
–the compiler builds upon it
– better performance
•close to Java’s performance
– code immune to « monkey patching »
•dynamic metaprogramming can interfere with your
framework’s code
– smaller generated bytecode
47
I canz do what
I want wiz
your code
I canz do what
I want wiz
your code
Niark !
Drawbacks for static compilation
• We lose...
– Some dynamic features
•metaclass changes, categories
– Method « dynamic dispatch » can differ
•but thanks to type inference, it’s as close as «classical»
Groovy as possible
49
Mix statically compiled code with dynamic
@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()
}
50
Mix statically compiled code with dynamic
@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()
}
Statically compiled
50
Mix statically compiled code with dynamic
@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()
}
Statically compiled
Dynamic
50
Mix statically compiled code with dynamic
@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()
}
Statically compiled
Dynamic
Call a
method with
dynamic
content
50
Mix statically compiled code with dynamic
@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()
}
Statically compiled
Dynamic
Call a
method with
dynamic
content
Method signatures
are a contract!
50
What about performance?
• Comparisons between:
– Java
– Groovy
•with static compilation (Groovy 2.0)
•with primitive type optimization (Groovy 1.8)
•no optimization (Groovy 1.7)
51
What about performance?
Fibonacci
Pi (π)
quadrature
Binary
trees
Java
Static
compilation
Primitive
optimizations
No prim.
optimizations
191 ms 97 ms 3.6 s
197 ms 101 ms 4.3 s
360 ms 111 ms 23.7 s
2590 ms 3220 ms 50.0 s
1.71.82.x
52
...and now, onto
Groovy2.1
Complete Invoke Dynamic support
Meta-annotations
Advanced compilerconfiguration
Typecheckerextensions
Invoke
Dynamic
Complete support
of Invoke Dynamic
Meta-annotations
One annotation
to rule them all!
Meta-annotations
• Create meta-annotations which combine
and/or parameterize other annotations
• And which work with AST transformations
56
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected annotations
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected annotations
The collector
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected annotations
The collector
Your own
annotation
alias
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
@MyAlias
class	
  Person	
  {
	
  	
  	
  	
  String	
  name
	
  	
  	
  	
  int	
  age
}
Collected annotations
The collector
Your own
annotation
alias
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
@MyAlias
class	
  Person	
  {
	
  	
  	
  	
  String	
  name
	
  	
  	
  	
  int	
  age
}
Collected annotations
The collector
Your own
annotation
alias
Use your meta-
annotation
57
@DelegatesTo
annotation
Richer tooling support
for Domain-Specific Languages
@DelegatesTo annotation
• Static type checking works fine with a certain
range of DSLs
– « command chains », extension methods...
• But less for DSLs using closure delegation
– often used by DSLs like in Gradle
task	
  copyTask(type:	
  Copy)	
  {
	
  	
  	
  	
  from	
  'src/main/webapp'
	
  	
  	
  	
  into	
  'build/explodedWar'
}
59
@DelegatesTo annotation
exec(spec)	
  {
	
  	
  	
  	
  foo()
}
60
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
exec(spec)	
  {
	
  	
  	
  	
  foo()
}
60
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
exec(spec)	
  {
	
  	
  	
  	
  foo()
}
60
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
exec(spec)	
  {
	
  	
  	
  	
  foo()
}
The static type checker doesn’t
know about method foo()
60
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c()
}
exec(spec)	
  {
	
  	
  	
  	
  foo()
}
Annotate with
@DelegatesTo(ExecSpec)
The static type checker doesn’t
know about method foo()
60
@DelegatesTo annotation
• With another
delegation strategy
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c.resolveStrategy	
  =	
  DELEGATE_FIRST
	
  	
  	
  	
  c()
}
61
@DelegatesTo annotation
• With another
delegation strategy
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  	
  c.delegate	
  =	
  sp
	
  	
  	
  	
  c.resolveStrategy	
  =	
  DELEGATE_FIRST
	
  	
  	
  	
  c()
}
Annotate with
@DelegatesTo(value = ExecSpec,
strategy = DELEGATE_FIRST)
61
@DelegatesTo annotation
• Very interesting for DSLs using closure’s
delegation strategy
• Excellent for...
– documenting your APIs
– the integration within the IDE
•code completion, code navigation
– works well with static type checking and
static compilation
62
Extend the static
type checker
To go even further
than Java itself!
Extend the static type checker
• Extend the type checker to make it smarter!
– even smarter than Java’s! :-)
• By creating your own extension
@TypeChecked(extensions	
  =	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'MyExtension.groovy')
void	
  exec()	
  {
	
  	
  	
  	
  //	
  code	
  to	
  be	
  further	
  checked...
}
64
Extend the static type checker
• Extend the type checker to make it smarter!
– even smarter than Java’s! :-)
• By creating your own extension
@TypeChecked(extensions	
  =	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  'MyExtension.groovy')
void	
  exec()	
  {
	
  	
  	
  	
  //	
  code	
  to	
  be	
  further	
  checked...
}
We could use a
meta-annotation
64
Extend the static type checker
• Help the static type checker when...
– impossible to infer types
– no matching method found
– no matching attribute found
– on wrong variable assignment
– ...
65
Extend the static type checker
• Your extension has access to an event-
oriented API
66
• onMethodSelection
• afterMethodCall
• beforeMethodCall
• afterVisitMethod
• beforeVisitMethod
• methodNotFound
• unresolvedVariable
• unresolvedProperty
• unresolvedAttribute
• incompatibleAssignment
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }
67
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }
MyExtension.groovy
67
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }
MyExtension.groovy
Learn your
Groovy AST!
67
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
  -­‐>	
  ...	
  }
unresolvedVariable	
  {	
  var	
  -­‐>	
  ...	
  }
methodNotFound	
  {	
  receiver,	
  name,	
  argList,	
  argTypes,	
  call	
  -­‐>	
  ...	
  }
incompatibleAssignment	
  {	
  lhsType,	
  rhsType,	
  expr	
  -­‐>	
  ...	
  }
MyExtension.groovy
Learn your
Groovy AST!
No need to be
pre-compiled
67
Extend the static type checker
• A few examples
– check that a string is a valid SQL query
– check the arguments and types of sprintf() method
calls so they match the pattern
68
Compiler
configuration
Custom base script class
Configuration script
Configuration DSL
Compiler customization
• Groovy 1.8 introduced « customizers »
– add imports transparently
– apply AST transformations by default
– filter / secure scripts
• With the « static type checker » and « static
compilation », we were asked if we could apply
them by default
70
Compiler customization
• New options
– --basescript
to define a base script class for your scripts
– --configscript
to indicate a script to configure the
CompilerConfiguration object
71
Compiler customization
• Add the @ToString AST transformation
import	
  groovy.transform.ToString
import	
  org.codehaus.groovy.control.customizers
	
  	
  	
  	
  	
  	
  	
  .ASTTransformationCustomizer
configuration.addCompilationCustomizer(
	
  	
  	
  	
  new	
  ASTTransformationCustomizer(ToString)
)
72
Compiler customization
• Add the @ToString AST transformation
import	
  groovy.transform.ToString
import	
  org.codehaus.groovy.control.customizers
	
  	
  	
  	
  	
  	
  	
  .ASTTransformationCustomizer
configuration.addCompilationCustomizer(
	
  	
  	
  	
  new	
  ASTTransformationCustomizer(ToString)
)
CompilerConfiguration instance,
injected by default
72
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  }
}
73
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  }
}
configuration.customizers	
  {
	
  	
  	
  	
  //	
  apply	
  to	
  *.gbean	
  files
	
  	
  	
  	
  source(extension:	
  '.gbean')	
  
{
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  }
}
73
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  apply	
  to	
  MyBean.groovy
	
  	
  	
  	
  source(basename:	
  'MyBean')	
  {
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  }
}
configuration.customizers	
  {
	
  	
  	
  	
  //	
  apply	
  to	
  *.gbean	
  files
	
  	
  	
  	
  source(extension:	
  '.gbean')	
  
{
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  }
}
configuration.customizers	
  {
	
  	
  	
  	
  //	
  custom	
  filter	
  logic
	
  	
  	
  	
  source(unitValidator:	
  {	
  unit	
  -­‐>	
  ...	
  })	
  
{
	
  	
  	
  	
  	
  	
  	
  	
  ast(ToString)
	
  	
  	
  	
  	
  	
  	
  	
  imports	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  staticStar	
  'java.lang.Math'
	
  	
  	
  	
  	
  	
  	
  	
  }
	
  	
  	
  	
  }
}
73
To learn more...
Groovy2.0
http://groovy.codehaus.org/Groovy+2.0+release+notes
Groovy2.1
http://groovy.codehaus.org/Groovy+2.1+release+notes
And what’s next?
Groovy2.2,2.3&3 !
New « MOP »
NewGrammar with Antlr v4
Java8Lambdassupport
A few words about the roadmap
2014201420132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
A few words about the roadmap
2014201420132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
A few words about the roadmap
2014201420132012
Groovy 2.1
Groovy 2.0Groovy 2.0 Groovy 2.2
Groovy 2.3
76
Groovy 3.0
Groovy 2.2
Implicitclosurecoercion
@Memoized transformation
DelegatingScript base script class
Implicit closure coercion
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
Given a predicate & a List method to
filter according to that predicate...
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
Given a predicate & a List method to
filter according to that predicate...
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
Given a predicate & a List method to
filter according to that predicate...
Java 8 lambdas can be
more concise than Groovy!
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
list.filter({	
  it.age	
  >	
  18	
  }	
  as	
  Predicate)
Given a predicate & a List method to
filter according to that predicate...
Java 8 lambdas can be
more concise than Groovy!
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
list.filter	
  {	
  it.age	
  >	
  18	
  }	
  
Given a predicate & a List method to
filter according to that predicate...
Java 8 lambdas can be
more concise than Groovy!
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
list.filter	
  {	
  it.age	
  >	
  18	
  }	
  
Given a predicate & a List method to
filter according to that predicate...
Java 8 lambdas can be
more concise than Groovy!
When no ambiguity,
make coercion implicit!
78
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predicate<T>	
  p)
list.filter((it)	
  -­‐>	
  it.age	
  >	
  18)
list.filter	
  {	
  it.age	
  >	
  18	
  }	
  
Given a predicate & a List method to
filter according to that predicate...
Java 8 lambdas can be
more concise than Groovy!
When no ambiguity,
make coercion implicit!
Go beyond Java, by making it
work on abstract classes too
78
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
79
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
Handy for
DSLs!
79
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
Handy for
DSLs!
name	
  =	
  "Guillaume"
sayHi()
79
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
class	
  Person	
  {
	
  	
  	
  	
  String	
  name
	
  	
  	
  	
  void	
  sayHi()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "Hi	
  $name"	
  
	
  	
  	
  	
  }
}
Handy for
DSLs!
name	
  =	
  "Guillaume"
sayHi()
79
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
class	
  Person	
  {
	
  	
  	
  	
  String	
  name
	
  	
  	
  	
  void	
  sayHi()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "Hi	
  $name"	
  
	
  	
  	
  	
  }
}
Handy for
DSLs!
name	
  =	
  "Guillaume"
sayHi()
Use Person’s name property
79
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegatee
class	
  Person	
  {
	
  	
  	
  	
  String	
  name
	
  	
  	
  	
  void	
  sayHi()	
  {	
  
	
  	
  	
  	
  	
  	
  	
  	
  println	
  "Hi	
  $name"	
  
	
  	
  	
  	
  }
}
Handy for
DSLs!
name	
  =	
  "Guillaume"
sayHi()
Use Person’s name property
Call Person#sayHi()
79
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
80
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
Specify DelegatingScript base class
80
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
Specify DelegatingScript base class
Parse the script
80
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
80
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
Run the script
80
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseClass	
  =	
  DelegatingScript.class.name
def	
  sh	
  =	
  new	
  GroovyShell(cc)
def	
  script	
  =	
  sh.parse(file)
def	
  p	
  =	
  new	
  Person()
script.setDelegate(p)
script.run()
assert	
  p.name	
  ==	
  "Guillaume"
Specify DelegatingScript base class
Parse the script
Define the delegate
Run the script
Be Happy!
80
groovysh doc command
81
groovysh doc command
Launches your browser with the
JavaDoc and GDK doc of the class
81
groovysh code completion
82
groovysh code completion
Import
completion
82
groovysh code completion
Import
completion
Method call
completion
82
@Memoized transformation
• Piggypack on Closure’s own memoization
capabilities, but applied to methods
@Memoized	
  int	
  expensiveOp(int	
  a,	
  int	
  b)	
  {
	
  	
  	
  	
  sleep	
  1000
	
  	
  	
  	
  return	
  a	
  +	
  b
}
//	
  one	
  second	
  to	
  return
expensiveOp(1,	
  2)
	
  
//	
  immediate	
  result	
  returned
expensiveOp(1,	
  2)
83
Miscelanous improvements
• Precompiled type checking extensions
• Further tweaks to Groovysh with code
completion, better error reporting...
• Better syntax highlighting in Groovy Console
• Various dependency upgrades (Gradle,Ant)
@TypeChecked(extensions	
  =	
  'fqn.MyExtension')
84
Additional GDK methods...
• groupBy() on arrays
• combinations(Closure)
• collectMany() on Iterables
• JsonSlurper’s parse(File) and parse(URL)
assert	
  [[2,	
  3],	
  [4,	
  5,	
  6]]
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  .combinations	
  {	
  x,	
  y	
  -­‐>	
  x*y	
  }	
  ==	
  
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  [8,	
  12,	
  10,	
  15,	
  12,	
  18]
85
Likely in
Groovy 2.3
Traits
GroovyDoc rewrite
New documentation & website
Trait implementation
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
  believe	
  I	
  can	
  fly!"
	
  	
  	
  	
  }
}
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
  believe	
  I	
  can	
  fly!"
	
  	
  	
  	
  }
}
A trait keyword applying
the @Trait transformation
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
  believe	
  I	
  can	
  fly!"
	
  	
  	
  	
  }
}
A trait keyword applying
the @Trait transformation
class	
  Car	
  implements	
  FlyingAbility	
  {}
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
  believe	
  I	
  can	
  fly!"
	
  	
  	
  	
  }
}
A trait keyword applying
the @Trait transformation
class	
  Car	
  implements	
  FlyingAbility	
  {}
A class «implements»
the trait
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
  believe	
  I	
  can	
  fly!"
	
  	
  	
  	
  }
}
A trait keyword applying
the @Trait transformation
class	
  Car	
  implements	
  FlyingAbility	
  {}
A class «implements»
the trait
def	
  c	
  =	
  new	
  Car()
assert	
  c.fly()	
  ==	
  "I	
  believe	
  I	
  can	
  fly!"
87
GroovyDoc rewrite
88
GroovyDoc rewrite
GroovyDoc != Sexy Doc
88
New documentation and website
• New reference documentation
and guides using AsciiDoctor
• New website with a refreshed
skin and the new
content
89
Groovy 3
New MOP
New Antlr v4 grammar
JDK 8 lambda support
MOP
2
Antlr4
grammar
λ
JDK
8
Summary
• A very rich and blossoming ecosystem
•Groovy 2.0
– more modular
– a static theme
•static type checking
•static compilation
– JDK 7 theme
•Invoke Dynamic support
•Project Coin syntax enhancements
95
Summary
•Groovy 2.1
– Invoke Dynamic support completed
– @DelegatesTo annotation
– type checker extensions for DSLs
– meta-annotations
96
Summary
• Groovy 2.2
– implicit closure coercion
– @Memoized transformation
– DelegatingScript for script DSLs
– groovysh improvements
97
Summary
• Groovy 2.3
– traits
– new GroovyDoc
– new documentation
– new website
98
Summary
• Groovy 3
– a new MOP (Meta-Object Protocol)
– a new grammar with Antlr v4
– the support of JDK 8 and lambdas
99
Questions&Answers
Thankyou!
@glaforge 
http://glaforge.appspot.com

http://gplus.to/glaforge 
Image credits
• lift-off: http://www.wpclipart.com/space/ships/space_shuttle/Space_Shuttle_liftoff.png
• anniversary: http://www.empowernetwork.com/fam/files/2013/03/happy_birthday_cake_with_candles-1920x1200.jpg
• cerisier: 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
• lunar module: http://www.clavius.org/img/lm-diag.gif
• tomates: http://www.infoescola.com/wp-content/uploads/2011/01/tomate.jpg
• patates: http://toooof.free.fr/blogs/captainslip/screenshots/pommes_de_terre.jpg
• coins: http://www.coins-jewelry.com/c22.png
• more coins: http://diamond-center.co.il/upload/articles/gold-coins1.jpg
• binary: http://okletsgo.co.uk/img/binary.jpg
• grumpy: https://si0.twimg.com/profile_images/3115998027/b47c180a703a5ffa7d1437a66f545dc0.jpeg
• singe: http://static.ddmcdn.com/gif/how-to-draw-animals-31.jpg
• warning: http://th07.deviantart.net/fs71/PRE/i/2012/261/8/6/warning_gangnam_style_zone_by_untoucheddesigns-d5f6bal.png
• coyote: http://nittygriddy.com/wp-content/uploads/2011/01/Wiley-Coyote-Help.jpg
• ring: http://img.banggood.com/images/upload/2012/limin/SKU028431_11.JPG
• magnifying glass: http://www.renders-graphiques.fr/image/upload/normal/loupe.png
• work in progress: http://www.sbscompany.org/multimedia/immagini/work-in-progress.png
• tab key: http://www.meganga.com/wp-content/uploads/2012/03/Tab-Key-Word-Tutorials.jpg
• chronomètre: http://www.moineau-instruments.com/59-thickbox/chronometre-mecanique-1-10-t15-mn-2-fonctions.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
102

Contenu connexe

Tendances

Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseAndrew Eisenberg
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8confGR8Conf
 
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
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Railselliando dias
 
groovy transforms
groovy transformsgroovy transforms
groovy transformsPaul King
 
Ruby, muito mais que reflexivo
Ruby, muito mais que reflexivoRuby, muito mais que reflexivo
Ruby, muito mais que reflexivoFabio Kung
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)HamletDRC
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 
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
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Heiko Behrens
 
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume LaforgeGR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume LaforgeGR8Conf
 

Tendances (20)

Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
 
Google Dart
Google DartGoogle Dart
Google Dart
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 
Clean code
Clean codeClean code
Clean code
 
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
 
Rapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and RailsRapid Development with Ruby/JRuby and Rails
Rapid Development with Ruby/JRuby and Rails
 
groovy transforms
groovy transformsgroovy transforms
groovy transforms
 
Clean code
Clean codeClean code
Clean code
 
Getting rid of backtracking
Getting rid of backtrackingGetting rid of backtracking
Getting rid of backtracking
 
Ruby, muito mais que reflexivo
Ruby, muito mais que reflexivoRuby, muito mais que reflexivo
Ruby, muito mais que reflexivo
 
Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)Groovy Ast Transformations (greach)
Groovy Ast Transformations (greach)
 
Java Performance MythBusters
Java Performance MythBustersJava Performance MythBusters
Java Performance MythBusters
 
Polyglot JVM
Polyglot JVMPolyglot JVM
Polyglot JVM
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
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"
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume LaforgeGR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 

Similaire à Lift-off with Groovy 2 ...and beyond

Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailszenMonkey
 
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019Paulo Clavijo
 
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
 
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
 
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
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java DevelopersYakov Fain
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEAHamletDRC
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitMichelangelo van Dam
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Cocoa for Web Developers
Cocoa for Web DevelopersCocoa for Web Developers
Cocoa for Web Developersgeorgebrock
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummaryAmal Khailtash
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Arthur Puthin
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 
CJP Unit-1 contd.pptx
CJP Unit-1 contd.pptxCJP Unit-1 contd.pptx
CJP Unit-1 contd.pptxRAJASEKHARV10
 

Similaire à Lift-off with Groovy 2 ...and beyond (20)

Metaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And GrailsMetaprogramming Techniques In Groovy And Grails
Metaprogramming Techniques In Groovy And Grails
 
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019Breaking Dependencies Legacy Code -  Cork Software Crafters - September 2019
Breaking Dependencies Legacy Code - Cork Software Crafters - September 2019
 
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
 
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
 
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?"
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Static Analysis in IDEA
Static Analysis in IDEAStatic Analysis in IDEA
Static Analysis in IDEA
 
Unit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnitUnit testing PHP apps with PHPUnit
Unit testing PHP apps with PHPUnit
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Cocoa for Web Developers
Cocoa for Web DevelopersCocoa for Web Developers
Cocoa for Web Developers
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Griffon @ Svwjug
Griffon @ SvwjugGriffon @ Svwjug
Griffon @ Svwjug
 
Golang for OO Programmers
Golang for OO ProgrammersGolang for OO Programmers
Golang for OO Programmers
 
Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...Static types on javascript?! Type checking approaches to ensure healthy appli...
Static types on javascript?! Type checking approaches to ensure healthy appli...
 
Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
CJP Unit-1 contd.pptx
CJP Unit-1 contd.pptxCJP Unit-1 contd.pptx
CJP Unit-1 contd.pptx
 
Class introduction in java
Class introduction in javaClass introduction in java
Class introduction in java
 

Plus de 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
 
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
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 

Plus de 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...
 
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
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
 

Dernier

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
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
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
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
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 

Dernier (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
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!
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
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
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 

Lift-off with Groovy 2 ...and beyond

  • 1. © 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission. GuillaumeLaforge @glaforge  Lift-offwithGroovy2 ...andbeyond!
  • 2. © 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission. GuillaumeLaforge @glaforge  Lift-offwithGroovy2 ...andbeyond!
  • 4. GuillaumeLaforge @glaforge  http://glaforge.appspot.com  http://gplus.to/glaforge  Presentation will be uploaded to https://speakerdeck.com/glaforge
  • 6. ...statically type checked and compiled as needed Groovy
  • 7. Syntax deriving from Java, thus easy to learn Groovy
  • 9.
  • 10. 10
  • 12.
  • 13.
  • 14.
  • 15.
  • 16. GVM
  • 17. Let’s start the engine Modularity Java 7: ProjectCoin & invokedynamic Static typechecking & compilation
  • 18. Modularity « Not everybody needs everything, all the time, at the same time! »
  • 19. Groovy modularity • The « groovy-all » weighted... 6 MB ! • In addition to the language, we have APIs: – template engine,Ant task scripting, Swing UI builder, JMX builder... • We want a lighter « core » – with APIs in the form of modules • Ability to wire in « extension methods » 16
  • 20. The new JARs • One smaller core JAR of 3 MB • Modules – console – docgenerator – groovydoc – groovysh – ant – bsf – jsr-223 – jmx – sql – swing – servlet – templates – test – testng – json – xml 17
  • 21. The new JARs • One smaller core JAR of 3 MB • Modules – console – docgenerator – groovydoc – groovysh – ant – bsf – jsr-223 – jmx – sql – swing – servlet – templates – test – testng – json – xml 17
  • 23. Extension modules • Create your own extension module – contribute instance methods package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric") 19
  • 24. Extension modules • Create your own extension module – contribute instance methods package  foo class  StringExtension  {        static  introduces(String  self,  String  name)  {                "Hi  ${name),  I’m  ${self}"        } } //  usage:  "Guillaume".introduces("Cédric") Same structure as categories 19
  • 25. Extension modules • Create your own extension module – contribute static methods 20 package  foo class  StaticStringExtension  {        static  hi(String  self)  {                "Hi!"        } } //  usage:  String.hi()
  • 26. Extension module descriptor • META-INF/ – services/ •org.codehaus.groovy.runtime.ExtensionModule moduleName  =  stringExtensions moduleVersion  =  1.0 //  comma  separated  list  of  FQN  class  names extensionClasses  =  foo.StringExtension //  comma  separated  list  of  FQN  class  names staticExtensionClasses  =   foo.StaticStringExtension 21
  • 27. Java 7 theme « ProjectCoin » syntax InvokeDynamic support
  • 28. Binary literals • In addition to decimal, octal and hexa • A new binary representation: int  x  =  0b10101111 assert  x  ==  175   byte  aByte  =  0b00100001 assert  aByte  ==  33   int  anInt  =  0b1010000101000101 assert  anInt  ==  41285 23
  • 29.
  • 30. Underscores in literals • Use underscores in number literals 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 25
  • 31. Multi-catch exception blocks • A single catch block to catch several exceptions at once, rather than duplicating blocks try  {        /*  ...  */ }  catch(IOException  |  NullPointerException  e)  {        /*  un  seul  bloc  */ } 26
  • 32. Woot!
  • 33. JDK 7 Invoke Dynamic support • A « flag » to compile with « indy » – we might propose a backport for JDK < 7 • Avantages – more runtime performance •well... in theory... – In the long term, we might replace •« call site caching » ➔ MethodHandles •« metaclass registry » ➔ ClassValues – and the JIT « inlines » code more easily 28
  • 34. A « static » theme Static type checking Static compilation
  • 35. Static type checking • Goal: make the compiler grumpy! – throw errors at compile-time •rather than at runtime 30
  • 36. We don’t need dynamic features all the time!
  • 37. We don’t need dynamic features all the time! Nah !
  • 38. Static type checking • A « grumpy » compiler should... – say when there’s a typo in a method or variable name – complain when a non-existent method is called – or on bad assignments or use a bad return type 32
  • 39. Static type checking • The compiler should infer types... – less explicit types and casts – fine grained type inference •« flow typing » •« lowest upper bound » 33
  • 40. Static type checking • But the compiler should understand extension methods – allows a good level of dynamism, despite the additional restrictions 34
  • 41. Typos import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme } 35
  • 42. Typos import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme } Compilation error 35
  • 43. Typos import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme } Compilation error Compilation error 35
  • 44. Typos import  groovy.transform.TypeChecked   void  method()  {}   @TypeChecked  test()  {        //  Cannot  find  matching  method  metthhoood()        metthhoood()          def  name  =  "Guillaume"        //  variable  naamme  is  undeclared        println  naamme } Compilation error Compilation error Annotation at the method or class level 35
  • 45. Wrong variable assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object()   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1' 36
  • 46. Wrong variable assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object()   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1' Compilation error 36
  • 47. Wrong variable assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object()   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1' Compilation error Compilation error 36
  • 48. Wrong variable assignments //  cannot  assign  value  of  type...  to  variable... int  x  =  new  Object() Set  set  =  new  Object()   String[]  strings  =  ['a','b','c'] int  str  =  strings[0]   //  cannot  find  matching  method  plus() int  i  =  0 i  +=  '1' Compilation error Compilation error Compilation error 36
  • 49. Wrong return type //  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 } 37
  • 50. Wrong return type //  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 } Compilation error 37
  • 51. Wrong return type //  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 } Compilation error In the end, call StringBuilder’s toString() 37
  • 52. 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        } } 38
  • 53. 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        } } Variable optionally typed 38
  • 54. 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        } } Variable optionally typed Type String infered 38
  • 55. 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        } } Variable optionally typed trim() method added dynamically by Groovy Type String infered 38
  • 56. 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        } } Variable optionally typed Array element type inferred trim() method added dynamically by Groovy Type String infered 38
  • 57. Mix dynamic & statically checked code @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() } 39
  • 58. Mix dynamic & statically checked code @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() } Statically checked 39
  • 59. Mix dynamic & statically checked code @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() } Statically checked Dynamic 39
  • 60. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } 40
  • 61. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } No need for casts 40
  • 62. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } No need for casts No need for casts 40
  • 63. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } No need for casts No need for castsUnderstand GDK’s method: String#multiply(int) 40
  • 64. Lowest Upper Bound • The smallest common « super » type – might be virtual (« non-denotable ») @TypeChecked  test()  {        //  an  integer  and  a  BigDecimal        return  [1234,  3.14] } 41
  • 65. Lowest Upper Bound • The smallest common « super » type – might be virtual (« non-denotable ») @TypeChecked  test()  {        //  an  integer  and  a  BigDecimal        return  [1234,  3.14] } Infered type: List<T extends Number & Comparable & Serializable> 41
  • 66. Flow typing • Static type checking « follows » the type of values assigned into variables @TypeChecked  test()  {        def  var  =  123                  //  int  infered        int  x  =  var                      //  var  is  an  int        var  =  "123"                      //  assign  a  String  into  var        x  =  var.toInteger()      //  no  cast  needed        var  =  123        x  =  var.toUpperCase()  //  error,  var  is  an  int  ! } 42
  • 68. Not really clean, your code! Grmmpf...no!
  • 69. Static type checking and dynamic code •Type checking happens at compile-time – @TypeChecked doesn’t change behavior! •do not confound with static compilation • Most dynamic features can’t be checked – metaclass changes, categories... – dynamic variables from the « script binding » • But compile-time metaprogramming OK – if enough type information is available 44
  • 70. But if it ain’t dynamic, can we compile it statically?
  • 71. But if it ain’t dynamic, can we compile it statically? But of course!!!
  • 72. Static compilation • Given the code is statically type checked, lots of type information was infered... so we can as well compile statically ! – ie. generate the same bytecode as javac • Also interesting when stuck on JDK < 7 to gain performance improvements 46
  • 73. Avantages of static compilation • We gain: – type safety •thanks to static type checking –the compiler builds upon it – better performance •close to Java’s performance – code immune to « monkey patching » •dynamic metaprogramming can interfere with your framework’s code – smaller generated bytecode 47
  • 74. I canz do what I want wiz your code
  • 75. I canz do what I want wiz your code Niark !
  • 76. Drawbacks for static compilation • We lose... – Some dynamic features •metaclass changes, categories – Method « dynamic dispatch » can differ •but thanks to type inference, it’s as close as «classical» Groovy as possible 49
  • 77. Mix statically compiled code with dynamic @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() } 50
  • 78. Mix statically compiled code with dynamic @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() } Statically compiled 50
  • 79. Mix statically compiled code with dynamic @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() } Statically compiled Dynamic 50
  • 80. Mix statically compiled code with dynamic @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() } Statically compiled Dynamic Call a method with dynamic content 50
  • 81. Mix statically compiled code with dynamic @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() } Statically compiled Dynamic Call a method with dynamic content Method signatures are a contract! 50
  • 82. What about performance? • Comparisons between: – Java – Groovy •with static compilation (Groovy 2.0) •with primitive type optimization (Groovy 1.8) •no optimization (Groovy 1.7) 51
  • 83. What about performance? Fibonacci Pi (π) quadrature Binary trees Java Static compilation Primitive optimizations No prim. optimizations 191 ms 97 ms 3.6 s 197 ms 101 ms 4.3 s 360 ms 111 ms 23.7 s 2590 ms 3220 ms 50.0 s 1.71.82.x 52
  • 84. ...and now, onto Groovy2.1 Complete Invoke Dynamic support Meta-annotations Advanced compilerconfiguration Typecheckerextensions
  • 87. Meta-annotations • Create meta-annotations which combine and/or parameterize other annotations • And which work with AST transformations 56
  • 91. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} Collected annotations The collector Your own annotation alias 57
  • 92. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} @MyAlias class  Person  {        String  name        int  age } Collected annotations The collector Your own annotation alias 57
  • 93. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} @MyAlias class  Person  {        String  name        int  age } Collected annotations The collector Your own annotation alias Use your meta- annotation 57
  • 95. @DelegatesTo annotation • Static type checking works fine with a certain range of DSLs – « command chains », extension methods... • But less for DSLs using closure delegation – often used by DSLs like in Gradle task  copyTask(type:  Copy)  {        from  'src/main/webapp'        into  'build/explodedWar' } 59
  • 96. @DelegatesTo annotation exec(spec)  {        foo() } 60
  • 97. @DelegatesTo annotation class  ExecSpec  {        void  foo() } exec(spec)  {        foo() } 60
  • 98. @DelegatesTo annotation class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  {        foo() } 60
  • 99. @DelegatesTo annotation class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  {        foo() } The static type checker doesn’t know about method foo() 60
  • 100. @DelegatesTo annotation class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  {        foo() } Annotate with @DelegatesTo(ExecSpec) The static type checker doesn’t know about method foo() 60
  • 101. @DelegatesTo annotation • With another delegation strategy void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c.resolveStrategy  =  DELEGATE_FIRST        c() } 61
  • 102. @DelegatesTo annotation • With another delegation strategy void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c.resolveStrategy  =  DELEGATE_FIRST        c() } Annotate with @DelegatesTo(value = ExecSpec, strategy = DELEGATE_FIRST) 61
  • 103. @DelegatesTo annotation • Very interesting for DSLs using closure’s delegation strategy • Excellent for... – documenting your APIs – the integration within the IDE •code completion, code navigation – works well with static type checking and static compilation 62
  • 104. Extend the static type checker To go even further than Java itself!
  • 105. Extend the static type checker • Extend the type checker to make it smarter! – even smarter than Java’s! :-) • By creating your own extension @TypeChecked(extensions  =                            'MyExtension.groovy') void  exec()  {        //  code  to  be  further  checked... } 64
  • 106. Extend the static type checker • Extend the type checker to make it smarter! – even smarter than Java’s! :-) • By creating your own extension @TypeChecked(extensions  =                            'MyExtension.groovy') void  exec()  {        //  code  to  be  further  checked... } We could use a meta-annotation 64
  • 107. Extend the static type checker • Help the static type checker when... – impossible to infer types – no matching method found – no matching attribute found – on wrong variable assignment – ... 65
  • 108. Extend the static type checker • Your extension has access to an event- oriented API 66 • onMethodSelection • afterMethodCall • beforeMethodCall • afterVisitMethod • beforeVisitMethod • methodNotFound • unresolvedVariable • unresolvedProperty • unresolvedAttribute • incompatibleAssignment
  • 109. Extend the static type checker onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } 67
  • 110. Extend the static type checker onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } MyExtension.groovy 67
  • 111. Extend the static type checker onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } MyExtension.groovy Learn your Groovy AST! 67
  • 112. Extend the static type checker onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } MyExtension.groovy Learn your Groovy AST! No need to be pre-compiled 67
  • 113. Extend the static type checker • A few examples – check that a string is a valid SQL query – check the arguments and types of sprintf() method calls so they match the pattern 68
  • 114. Compiler configuration Custom base script class Configuration script Configuration DSL
  • 115. Compiler customization • Groovy 1.8 introduced « customizers » – add imports transparently – apply AST transformations by default – filter / secure scripts • With the « static type checker » and « static compilation », we were asked if we could apply them by default 70
  • 116. Compiler customization • New options – --basescript to define a base script class for your scripts – --configscript to indicate a script to configure the CompilerConfiguration object 71
  • 117. Compiler customization • Add the @ToString AST transformation import  groovy.transform.ToString import  org.codehaus.groovy.control.customizers              .ASTTransformationCustomizer configuration.addCompilationCustomizer(        new  ASTTransformationCustomizer(ToString) ) 72
  • 118. Compiler customization • Add the @ToString AST transformation import  groovy.transform.ToString import  org.codehaus.groovy.control.customizers              .ASTTransformationCustomizer configuration.addCompilationCustomizer(        new  ASTTransformationCustomizer(ToString) ) CompilerConfiguration instance, injected by default 72
  • 119. Compiler customization • A small DSL to configure the customization configuration.customizers  {        //  apply  to  MyBean.groovy        source(basename:  'MyBean')  {                ast(ToString)        } } 73
  • 120. Compiler customization • A small DSL to configure the customization configuration.customizers  {        //  apply  to  MyBean.groovy        source(basename:  'MyBean')  {                ast(ToString)        } } configuration.customizers  {        //  apply  to  *.gbean  files        source(extension:  '.gbean')   {                ast(ToString)        } } 73
  • 121. Compiler customization • A small DSL to configure the customization configuration.customizers  {        //  apply  to  MyBean.groovy        source(basename:  'MyBean')  {                ast(ToString)        } } configuration.customizers  {        //  apply  to  *.gbean  files        source(extension:  '.gbean')   {                ast(ToString)        } } configuration.customizers  {        //  custom  filter  logic        source(unitValidator:  {  unit  -­‐>  ...  })   {                ast(ToString)                imports  {                        staticStar  'java.lang.Math'                }        } } 73
  • 123. And what’s next? Groovy2.2,2.3&3 ! New « MOP » NewGrammar with Antlr v4 Java8Lambdassupport
  • 124. A few words about the roadmap 2014201420132012 Groovy 2.1 Groovy 2.0Groovy 2.0 Groovy 2.2 Groovy 2.3 76 Groovy 3.0
  • 125. A few words about the roadmap 2014201420132012 Groovy 2.1 Groovy 2.0Groovy 2.0 Groovy 2.2 Groovy 2.3 76 Groovy 3.0
  • 126. A few words about the roadmap 2014201420132012 Groovy 2.1 Groovy 2.0Groovy 2.0 Groovy 2.2 Groovy 2.3 76 Groovy 3.0
  • 129. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) 78
  • 130. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) Given a predicate & a List method to filter according to that predicate... 78
  • 131. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) Given a predicate & a List method to filter according to that predicate... 78
  • 132. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) Given a predicate & a List method to filter according to that predicate... Java 8 lambdas can be more concise than Groovy! 78
  • 133. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) list.filter({  it.age  >  18  }  as  Predicate) Given a predicate & a List method to filter according to that predicate... Java 8 lambdas can be more concise than Groovy! 78
  • 134. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) list.filter  {  it.age  >  18  }   Given a predicate & a List method to filter according to that predicate... Java 8 lambdas can be more concise than Groovy! 78
  • 135. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) list.filter  {  it.age  >  18  }   Given a predicate & a List method to filter according to that predicate... Java 8 lambdas can be more concise than Groovy! When no ambiguity, make coercion implicit! 78
  • 136. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) list.filter((it)  -­‐>  it.age  >  18) list.filter  {  it.age  >  18  }   Given a predicate & a List method to filter according to that predicate... Java 8 lambdas can be more concise than Groovy! When no ambiguity, make coercion implicit! Go beyond Java, by making it work on abstract classes too 78
  • 137. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee 79
  • 138. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee Handy for DSLs! 79
  • 139. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee Handy for DSLs! name  =  "Guillaume" sayHi() 79
  • 140. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee class  Person  {        String  name        void  sayHi()  {                  println  "Hi  $name"          } } Handy for DSLs! name  =  "Guillaume" sayHi() 79
  • 141. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee class  Person  {        String  name        void  sayHi()  {                  println  "Hi  $name"          } } Handy for DSLs! name  =  "Guillaume" sayHi() Use Person’s name property 79
  • 142. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee class  Person  {        String  name        void  sayHi()  {                  println  "Hi  $name"          } } Handy for DSLs! name  =  "Guillaume" sayHi() Use Person’s name property Call Person#sayHi() 79
  • 143. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" 80
  • 144. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" Specify DelegatingScript base class 80
  • 145. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" Specify DelegatingScript base class Parse the script 80
  • 146. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" Specify DelegatingScript base class Parse the script Define the delegate 80
  • 147. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" Specify DelegatingScript base class Parse the script Define the delegate Run the script 80
  • 148. DelegatingScript base script class • Integration example: def  cc  =  new  CompilerConfiguration() cc.scriptBaseClass  =  DelegatingScript.class.name def  sh  =  new  GroovyShell(cc) def  script  =  sh.parse(file) def  p  =  new  Person() script.setDelegate(p) script.run() assert  p.name  ==  "Guillaume" Specify DelegatingScript base class Parse the script Define the delegate Run the script Be Happy! 80
  • 150. groovysh doc command Launches your browser with the JavaDoc and GDK doc of the class 81
  • 154. @Memoized transformation • Piggypack on Closure’s own memoization capabilities, but applied to methods @Memoized  int  expensiveOp(int  a,  int  b)  {        sleep  1000        return  a  +  b } //  one  second  to  return expensiveOp(1,  2)   //  immediate  result  returned expensiveOp(1,  2) 83
  • 155. Miscelanous improvements • Precompiled type checking extensions • Further tweaks to Groovysh with code completion, better error reporting... • Better syntax highlighting in Groovy Console • Various dependency upgrades (Gradle,Ant) @TypeChecked(extensions  =  'fqn.MyExtension') 84
  • 156. Additional GDK methods... • groupBy() on arrays • combinations(Closure) • collectMany() on Iterables • JsonSlurper’s parse(File) and parse(URL) assert  [[2,  3],  [4,  5,  6]]                    .combinations  {  x,  y  -­‐>  x*y  }  ==                                            [8,  12,  10,  15,  12,  18] 85
  • 157. Likely in Groovy 2.3 Traits GroovyDoc rewrite New documentation & website
  • 159. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } 87
  • 160. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation 87
  • 161. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation class  Car  implements  FlyingAbility  {} 87
  • 162. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation class  Car  implements  FlyingAbility  {} A class «implements» the trait 87
  • 163. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation class  Car  implements  FlyingAbility  {} A class «implements» the trait def  c  =  new  Car() assert  c.fly()  ==  "I  believe  I  can  fly!" 87
  • 166. New documentation and website • New reference documentation and guides using AsciiDoctor • New website with a refreshed skin and the new content 89
  • 167. Groovy 3 New MOP New Antlr v4 grammar JDK 8 lambda support
  • 168. MOP 2
  • 171.
  • 172. Summary • A very rich and blossoming ecosystem •Groovy 2.0 – more modular – a static theme •static type checking •static compilation – JDK 7 theme •Invoke Dynamic support •Project Coin syntax enhancements 95
  • 173. Summary •Groovy 2.1 – Invoke Dynamic support completed – @DelegatesTo annotation – type checker extensions for DSLs – meta-annotations 96
  • 174. Summary • Groovy 2.2 – implicit closure coercion – @Memoized transformation – DelegatingScript for script DSLs – groovysh improvements 97
  • 175. Summary • Groovy 2.3 – traits – new GroovyDoc – new documentation – new website 98
  • 176. Summary • Groovy 3 – a new MOP (Meta-Object Protocol) – a new grammar with Antlr v4 – the support of JDK 8 and lambdas 99
  • 179. Image credits • lift-off: http://www.wpclipart.com/space/ships/space_shuttle/Space_Shuttle_liftoff.png • anniversary: http://www.empowernetwork.com/fam/files/2013/03/happy_birthday_cake_with_candles-1920x1200.jpg • cerisier: 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 • lunar module: http://www.clavius.org/img/lm-diag.gif • tomates: http://www.infoescola.com/wp-content/uploads/2011/01/tomate.jpg • patates: http://toooof.free.fr/blogs/captainslip/screenshots/pommes_de_terre.jpg • coins: http://www.coins-jewelry.com/c22.png • more coins: http://diamond-center.co.il/upload/articles/gold-coins1.jpg • binary: http://okletsgo.co.uk/img/binary.jpg • grumpy: https://si0.twimg.com/profile_images/3115998027/b47c180a703a5ffa7d1437a66f545dc0.jpeg • singe: http://static.ddmcdn.com/gif/how-to-draw-animals-31.jpg • warning: http://th07.deviantart.net/fs71/PRE/i/2012/261/8/6/warning_gangnam_style_zone_by_untoucheddesigns-d5f6bal.png • coyote: http://nittygriddy.com/wp-content/uploads/2011/01/Wiley-Coyote-Help.jpg • ring: http://img.banggood.com/images/upload/2012/limin/SKU028431_11.JPG • magnifying glass: http://www.renders-graphiques.fr/image/upload/normal/loupe.png • work in progress: http://www.sbscompany.org/multimedia/immagini/work-in-progress.png • tab key: http://www.meganga.com/wp-content/uploads/2012/03/Tab-Key-Word-Tutorials.jpg • chronomètre: http://www.moineau-instruments.com/59-thickbox/chronometre-mecanique-1-10-t15-mn-2-fonctions.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 102