0
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
GuillaumeLaforge
@glaforge 
Lift-off...
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.
GuillaumeLaforge
@glaforge 
Lift-off...
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
htt...
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,A...
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console
– docgenerator
– groovydoc
– groovysh
– ant
– bsf
– jsr-22...
The new JARs
• One smaller core JAR of 3 MB
• Modules
– console
– docgenerator
– groovydoc
– groovysh
– ant
– bsf
– jsr-22...
« Let’s go
shopping »
Extension modules
• Create your own extension module
– contribute instance methods
package	
  foo
class	
  StringExtension...
Extension modules
• Create your own extension module
– contribute instance methods
package	
  foo
class	
  StringExtension...
Extension modules
• Create your own extension module
– contribute static methods
20
package	
  foo
class	
  StaticStringEx...
Extension module descriptor
• META-INF/
– services/
•org.codehaus.groovy.runtime.ExtensionModule
moduleName	
  =	
  string...
Java 7
theme
« ProjectCoin » syntax
InvokeDynamic support
Binary literals
• In addition to decimal, octal and hexa
• A new binary representation:
int	
  x	
  =	
  0b10101111
assert...
Underscores in literals
• Use underscores in number literals
long	
  creditCardNumber	
  =	
  1234_5678_9012_3456L
long	
 ...
Multi-catch exception blocks
• A single catch block to catch several exceptions
at once, rather than duplicating blocks
tr...
Woot!
JDK 7 Invoke Dynamic support
• A « flag » to compile with « indy »
– we might propose a backport for JDK < 7
• Avantages
– ...
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 w...
Static type checking
• The compiler should infer types...
– less explicit types and casts
– fine grained type inference
•« ...
Static type checking
• But the compiler should understand
extension methods
– allows a good level of dynamism,
despite the...
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  ...
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  ...
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  ...
Typos
import	
  groovy.transform.TypeChecked
	
  
void	
  method()	
  {}
	
  
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  ...
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  O...
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  O...
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  O...
Wrong variable assignments
//	
  cannot	
  assign	
  value	
  of	
  type...	
  to	
  variable...
int	
  x	
  =	
  new	
  O...
Wrong return type
//	
  checks	
  if/else	
  branch	
  return	
  values
@TypeChecked
int	
  method()	
  {
	
  	
  	
  	
  ...
Wrong return type
//	
  checks	
  if/else	
  branch	
  return	
  values
@TypeChecked
int	
  method()	
  {
	
  	
  	
  	
  ...
Wrong return type
//	
  checks	
  if/else	
  branch	
  return	
  values
@TypeChecked
int	
  method()	
  {
	
  	
  	
  	
  ...
Type inference
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
	
  
	
  	
  	
...
Type inference
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
	
  
	
  	
  	
...
Type inference
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
	
  
	
  	
  	
...
Type inference
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
	
  
	
  	
  	
...
Type inference
@TypeChecked	
  test()	
  {
	
  	
  	
  	
  def	
  name	
  =	
  "	
  	
  Guillaume	
  	
  "
	
  
	
  	
  	
...
Mix dynamic & statically checked code
@TypeChecked
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  call	
  m...
Mix dynamic & statically checked code
@TypeChecked
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  call	
  m...
Mix dynamic & statically checked code
@TypeChecked
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  call	
  m...
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
 ...
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
 ...
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
 ...
Instanceof checks
@TypeChecked	
  
void	
  test(Object	
  val)	
  {
	
  	
  	
  	
  if	
  (val	
  instanceof	
  String)	
 ...
Lowest Upper Bound
• The smallest common « super » type
– might be virtual (« non-denotable »)
@TypeChecked	
  test()	
  {...
Lowest Upper Bound
• The smallest common « super » type
– might be virtual (« non-denotable »)
@TypeChecked	
  test()	
  {...
Flow typing
• Static type checking « follows » the type of values
assigned into variables
@TypeChecked	
  test()	
  {
	
  ...
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 n...
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 ...
Avantages of static compilation
• We gain:
– type safety
•thanks to static type checking
–the compiler builds upon it
– be...
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 di...
Mix statically compiled code with dynamic
@CompileStatic
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  cal...
Mix statically compiled code with dynamic
@CompileStatic
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  cal...
Mix statically compiled code with dynamic
@CompileStatic
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  cal...
Mix statically compiled code with dynamic
@CompileStatic
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  cal...
Mix statically compiled code with dynamic
@CompileStatic
String	
  greeting(String	
  name)	
  {
	
  	
  	
  	
  //	
  cal...
What about performance?
• Comparisons between:
– Java
– Groovy
•with static compilation (Groovy 2.0)
•with primitive type ...
What about performance?
Fibonacci
Pi (π)
quadrature
Binary
trees
Java
Static
compilation
Primitive
optimizations
No prim.
...
...and now, onto
Groovy2.1
Complete Invoke Dynamic support
Meta-annotations
Advanced compilerconfiguration
Typecheckerexte...
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 t...
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
57
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected...
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected...
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
Collected...
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
@MyAlias
...
Meta-annotations
@Immutable
@ToString(excludes	
  =	
  ["age"])
@AnnotationCollector
@interface	
  MyAlias	
  {}
@MyAlias
...
@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 meth...
@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	
  ...
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
void	
  exec(ExecSpec	
  sp,	
  Closure	
  ...
@DelegatesTo annotation
class	
  ExecSpec	
  {
	
  	
  	
  	
  void	
  foo()
}
void	
  exec(ExecSpec	
  sp,	
  Closure	
  ...
@DelegatesTo annotation
• With another
delegation strategy
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  ...
@DelegatesTo annotation
• With another
delegation strategy
void	
  exec(ExecSpec	
  sp,	
  Closure	
  c)	
  {
	
  	
  	
  ...
@DelegatesTo annotation
• Very interesting for DSLs using closure’s
delegation strategy
• Excellent for...
– documenting y...
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...
Extend the static type checker
• Extend the type checker to make it smarter!
– even smarter than Java’s! :-)
• By creating...
Extend the static type checker
• Help the static type checker when...
– impossible to infer types
– no matching method fou...
Extend the static type checker
• Your extension has access to an event-
oriented API
66
• onMethodSelection
• afterMethodC...
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
 ...
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
 ...
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
 ...
Extend the static type checker
onMethodSelection	
  {	
  expr,	
  method	
  -­‐>	
  ...	
  }
afterMethodCall	
  {	
  mc	
 ...
Extend the static type checker
• A few examples
– check that a string is a valid SQL query
– check the arguments and types...
Compiler
configuration
Custom base script class
Configuration script
Configuration DSL
Compiler customization
• Groovy 1.8 introduced « customizers »
– add imports transparently
– apply AST transformations by ...
Compiler customization
• New options
– --basescript
to define a base script class for your scripts
– --configscript
to indic...
Compiler customization
• Add the @ToString AST transformation
import	
  groovy.transform.ToString
import	
  org.codehaus.g...
Compiler customization
• Add the @ToString AST transformation
import	
  groovy.transform.ToString
import	
  org.codehaus.g...
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  ap...
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  ap...
Compiler customization
• A small DSL to configure the customization
configuration.customizers	
  {
	
  	
  	
  	
  //	
  ap...
To learn more...
Groovy2.0
http://groovy.codehaus.org/Groovy+2.0+release+notes
Groovy2.1
http://groovy.codehaus.org/Groovy...
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(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
Implicit closure coercion
interface	
  Predicate<T>	
  {
	
  	
  	
  	
  boolean	
  test(T	
  t)
}
List<T>	
  filter(Predi...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Special base script class to delegate method
calls and property accesses to a delegat...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
DelegatingScript base script class
• Integration example:
def	
  cc	
  =	
  new	
  CompilerConfiguration()
cc.scriptBaseCl...
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	
 ...
Miscelanous improvements
• Precompiled type checking extensions
• Further tweaks to Groovysh with code
completion, better ...
Additional GDK methods...
• groupBy() on arrays
• combinations(Closure)
• collectMany() on Iterables
• JsonSlurper’s parse...
Likely in
Groovy 2.3
Traits
GroovyDoc rewrite
New documentation & website
Trait implementation
87
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
...
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
...
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
...
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
...
Trait implementation
trait	
  FlyingAbility	
  {
	
  	
  	
  	
  String	
  fly()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  "I	
...
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
sk...
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 c...
Summary
•Groovy 2.1
– Invoke Dynamic support completed
– @DelegatesTo annotation
– type checker extensions for DSLs
– meta...
Summary
• Groovy 2.2
– implicit closure coercion
– @Memoized transformation
– DelegatingScript for script DSLs
– groovysh ...
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...
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
Upcoming SlideShare
Loading in...5
×

Lift off with Groovy 2 at JavaOne 2013

1,897

Published on

Presentations on the features of the Groovy 2.x line

Published in: Technology, Business
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,897
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
39
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Transcript of "Lift off with Groovy 2 at JavaOne 2013"

  1. 1. © 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission. GuillaumeLaforge @glaforge  Lift-offwithGroovy2 ...andbeyond!
  2. 2. © 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission. GuillaumeLaforge @glaforge  Lift-offwithGroovy2 ...andbeyond!
  3. 3. GuillaumeLaforge @glaforge  http://glaforge.appspot.com  http://gplus.to/glaforge 
  4. 4. GuillaumeLaforge @glaforge  http://glaforge.appspot.com  http://gplus.to/glaforge  Presentation will be uploaded to https://speakerdeck.com/glaforge
  5. 5. A dynamic language, optionally typed Groovy
  6. 6. ...statically type checked and compiled as needed Groovy
  7. 7. Syntax deriving from Java, thus easy to learn Groovy
  8. 8. million downloads in 2012 1.7
  9. 9. 10
  10. 10. Ablossoming Ecosystem
  11. 11. GVM
  12. 12. Let’s start the engine Modularity Java 7: ProjectCoin & invokedynamic Static typechecking & compilation
  13. 13. Modularity « Not everybody needs everything, all the time, at the same time! »
  14. 14. 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
  15. 15. 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
  16. 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
  17. 17. « Let’s go shopping »
  18. 18. 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
  19. 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
  20. 20. Extension modules • Create your own extension module – contribute static methods 20 package  foo class  StaticStringExtension  {        static  hi(String  self)  {                "Hi!"        } } //  usage:  String.hi()
  21. 21. 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
  22. 22. Java 7 theme « ProjectCoin » syntax InvokeDynamic support
  23. 23. 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
  24. 24. 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
  25. 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
  26. 26. Woot!
  27. 27. 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
  28. 28. A « static » theme Static type checking Static compilation
  29. 29. Static type checking • Goal: make the compiler grumpy! – throw errors at compile-time •rather than at runtime 30
  30. 30. We don’t need dynamic features all the time!
  31. 31. We don’t need dynamic features all the time! Nah !
  32. 32. 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
  33. 33. Static type checking • The compiler should infer types... – less explicit types and casts – fine grained type inference •« flow typing » •« lowest upper bound » 33
  34. 34. Static type checking • But the compiler should understand extension methods – allows a good level of dynamism, despite the additional restrictions 34
  35. 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 } 35
  36. 36. 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
  37. 37. 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
  38. 38. 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
  39. 39. 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
  40. 40. 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
  41. 41. 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
  42. 42. 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
  43. 43. 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
  44. 44. 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
  45. 45. 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
  46. 46. 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
  47. 47. Type inference @TypeChecked  test()  {        def  name  =  "    Guillaume    "          //  String  type  infered  (even  inside  GString)        println  "NAME  =  ${name.toUpperCase()}"            //  Groovy  GDK  method  support        //  (GDK  operator  overloading  too)        println  name.trim()          int[]  numbers  =  [1,  2,  3]        //  Element  n  is  an  int        for  (int  n  in  numbers)  {                println  n        } } Variable optionally typed 38
  48. 48. 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
  49. 49. 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
  50. 50. 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
  51. 51. 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
  52. 52. 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
  53. 53. 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
  54. 54. Instanceof checks @TypeChecked   void  test(Object  val)  {        if  (val  instanceof  String)  {                println  val.toUpperCase()        }  else  if  (val  instanceof  Number)  {                println  "X"  *  val.intValue()        } } 40
  55. 55. 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
  56. 56. 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
  57. 57. 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
  58. 58. 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
  59. 59. 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
  60. 60. 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
  61. 61. Not really clean, your code!
  62. 62. Not really clean, your code! Grmmpf...no!
  63. 63. 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
  64. 64. But if it ain’t dynamic, can we compile it statically?
  65. 65. But if it ain’t dynamic, can we compile it statically? But of course!!!
  66. 66. 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
  67. 67. 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
  68. 68. I canz do what I want wiz your code
  69. 69. I canz do what I want wiz your code Niark !
  70. 70. 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
  71. 71. 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
  72. 72. 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
  73. 73. 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
  74. 74. 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
  75. 75. 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
  76. 76. 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
  77. 77. 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
  78. 78. ...and now, onto Groovy2.1 Complete Invoke Dynamic support Meta-annotations Advanced compilerconfiguration Typecheckerextensions
  79. 79. Invoke Dynamic Complete support of Invoke Dynamic
  80. 80. Meta-annotations One annotation to rule them all!
  81. 81. Meta-annotations • Create meta-annotations which combine and/or parameterize other annotations • And which work with AST transformations 56
  82. 82. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} 57
  83. 83. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} Collected annotations 57
  84. 84. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} Collected annotations The collector 57
  85. 85. Meta-annotations @Immutable @ToString(excludes  =  ["age"]) @AnnotationCollector @interface  MyAlias  {} Collected annotations The collector Your own annotation alias 57
  86. 86. 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
  87. 87. 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
  88. 88. @DelegatesTo annotation Richer tooling support for Domain-Specific Languages
  89. 89. @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
  90. 90. @DelegatesTo annotation exec(spec)  {        foo() } 60
  91. 91. @DelegatesTo annotation class  ExecSpec  {        void  foo() } exec(spec)  {        foo() } 60
  92. 92. @DelegatesTo annotation class  ExecSpec  {        void  foo() } void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c() } exec(spec)  {        foo() } 60
  93. 93. @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
  94. 94. @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
  95. 95. @DelegatesTo annotation • With another delegation strategy void  exec(ExecSpec  sp,  Closure  c)  {        c.delegate  =  sp        c.resolveStrategy  =  DELEGATE_FIRST        c() } 61
  96. 96. @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
  97. 97. @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
  98. 98. Extend the static type checker To go even further than Java itself!
  99. 99. 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
  100. 100. 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
  101. 101. 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
  102. 102. 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
  103. 103. Extend the static type checker onMethodSelection  {  expr,  method  -­‐>  ...  } afterMethodCall  {  mc  -­‐>  ...  } unresolvedVariable  {  var  -­‐>  ...  } methodNotFound  {  receiver,  name,  argList,  argTypes,  call  -­‐>  ...  } incompatibleAssignment  {  lhsType,  rhsType,  expr  -­‐>  ...  } 67
  104. 104. 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
  105. 105. 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
  106. 106. 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
  107. 107. 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
  108. 108. Compiler configuration Custom base script class Configuration script Configuration DSL
  109. 109. 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
  110. 110. 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
  111. 111. Compiler customization • Add the @ToString AST transformation import  groovy.transform.ToString import  org.codehaus.groovy.control.customizers              .ASTTransformationCustomizer configuration.addCompilationCustomizer(        new  ASTTransformationCustomizer(ToString) ) 72
  112. 112. 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
  113. 113. Compiler customization • A small DSL to configure the customization configuration.customizers  {        //  apply  to  MyBean.groovy        source(basename:  'MyBean')  {                ast(ToString)        } } 73
  114. 114. 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
  115. 115. 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
  116. 116. 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
  117. 117. And what’s next? Groovy2.2,2.3&3 ! New « MOP » NewGrammar with Antlr v4 Java8Lambdassupport
  118. 118. 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
  119. 119. 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
  120. 120. 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
  121. 121. Groovy 2.2 Implicitclosurecoercion @Memoized transformation DelegatingScript base script class
  122. 122. Implicit closure coercion 78
  123. 123. Implicit closure coercion interface  Predicate<T>  {        boolean  test(T  t) } List<T>  filter(Predicate<T>  p) 78
  124. 124. 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
  125. 125. 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
  126. 126. 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
  127. 127. 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
  128. 128. 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
  129. 129. 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
  130. 130. 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
  131. 131. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee 79
  132. 132. DelegatingScript base script class • Special base script class to delegate method calls and property accesses to a delegatee Handy for DSLs! 79
  133. 133. 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
  134. 134. 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
  135. 135. 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
  136. 136. 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
  137. 137. 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
  138. 138. 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
  139. 139. 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
  140. 140. 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
  141. 141. 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
  142. 142. 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
  143. 143. groovysh doc command 81
  144. 144. groovysh doc command Launches your browser with the JavaDoc and GDK doc of the class 81
  145. 145. groovysh code completion 82
  146. 146. groovysh code completion Import completion 82
  147. 147. groovysh code completion Import completion Method call completion 82
  148. 148. @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
  149. 149. 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
  150. 150. 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
  151. 151. Likely in Groovy 2.3 Traits GroovyDoc rewrite New documentation & website
  152. 152. Trait implementation 87
  153. 153. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } 87
  154. 154. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation 87
  155. 155. Trait implementation trait  FlyingAbility  {        String  fly()  {                "I  believe  I  can  fly!"        } } A trait keyword applying the @Trait transformation class  Car  implements  FlyingAbility  {} 87
  156. 156. 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
  157. 157. 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
  158. 158. GroovyDoc rewrite 88
  159. 159. GroovyDoc rewrite GroovyDoc != Sexy Doc 88
  160. 160. New documentation and website • New reference documentation and guides using AsciiDoctor • New website with a refreshed skin and the new content 89
  161. 161. Groovy 3 New MOP New Antlr v4 grammar JDK 8 lambda support
  162. 162. MOP 2
  163. 163. Antlr4 grammar
  164. 164. λ JDK 8
  165. 165. 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
  166. 166. Summary •Groovy 2.1 – Invoke Dynamic support completed – @DelegatesTo annotation – type checker extensions for DSLs – meta-annotations 96
  167. 167. Summary • Groovy 2.2 – implicit closure coercion – @Memoized transformation – DelegatingScript for script DSLs – groovysh improvements 97
  168. 168. Summary • Groovy 2.3 – traits – new GroovyDoc – new documentation – new website 98
  169. 169. Summary • Groovy 3 – a new MOP (Meta-Object Protocol) – a new grammar with Antlr v4 – the support of JDK 8 and lambdas 99
  170. 170. Questions&Answers
  171. 171. Thankyou! @glaforge  http://glaforge.appspot.com  http://gplus.to/glaforge 
  172. 172. 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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×