Slide 1

Slide 1 text

Groovy in 2014 and beyond Guillaume Laforge Groovy project lead Pivotal @glaforge

Slide 2

Slide 2 text

Stay up-to-date Groovy Weekly Newsletter (Every Tuesday) http://beta.groovy-lang.org/groovy-weekly.html 2

Slide 3

Slide 3 text

The Groovy roadmap 3 2015 2014 2013 Groovy 2.3 Groovy 2.4 Groovy 2.2 Groovy 2.5 ? Groovy 3.0 ?

Slide 4

Slide 4 text

@glaforge — Groovy in 2014 and beyond Groovy 2.3

Slide 5

Slide 5 text

@glaforge — Groovy in 2014 and beyond JDK 8 support

Slide 6

Slide 6 text

JDK 8 support — closures vs lambdas 6 IntStream.range(1,  100).forEach(s  -­‐>                                                System.out.println(s));   ! Files.lines(Paths.get('README.adoc'))            .map(it  -­‐>  it.toUpperCase())            .forEach(it  -­‐>  System.out.println(it));

Slide 7

Slide 7 text

JDK 8 support — closures vs lambdas 6 IntStream.range(1,  100).forEach(s  -­‐>                                                System.out.println(s));   ! Files.lines(Paths.get('README.adoc'))            .map(it  -­‐>  it.toUpperCase())            .forEach(it  -­‐>  System.out.println(it)); IntStream.range(1,  100).forEach  {  println  it  }   ! Files.lines(Paths.get('README.adoc'))            .map  {  it.toUpperCase()  }            .forEach  {  println  it  }

Slide 8

Slide 8 text

JDK 8 support — closures vs lambdas 6 IntStream.range(1,  100).forEach(s  -­‐>                                                System.out.println(s));   ! Files.lines(Paths.get('README.adoc'))            .map(it  -­‐>  it.toUpperCase())            .forEach(it  -­‐>  System.out.println(it)); IntStream.range(1,  100).forEach  {  println  it  }   ! Files.lines(Paths.get('README.adoc'))            .map  {  it.toUpperCase()  }            .forEach  {  println  it  } Use Groovy closures wherever you pass lambdas in Java 8

Slide 9

Slide 9 text

@glaforge — Groovy in 2014 and beyond Traits

Slide 10

Slide 10 text

Traits • Like interfaces, but with method bodies • similar to Java 8 interface default methods • Elegant way to compose behavior • multiple inheritance without the « diamond » problem • Traits can also be stateful • traits can have properties like normal classes • Compatible with static typing and static compilation • class methods from traits also visible from Java classes • Also possible to implement traits at runtime 8

Slide 11

Slide 11 text

Traits: a simple example 9 trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird()   ! assert  b.fly()  ==  "I'm  flying!"

Slide 12

Slide 12 text

Traits: a simple example 9 trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird()   ! assert  b.fly()  ==  "I'm  flying!" « trait », a new keyword for a new concept

Slide 13

Slide 13 text

Traits: a simple example 9 trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird()   ! assert  b.fly()  ==  "I'm  flying!" a class 
 « implements »
 a trait

Slide 14

Slide 14 text

Traits: a simple example 9 trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird()   ! assert  b.fly()  ==  "I'm  flying!" the fly() method from the trait is available

Slide 15

Slide 15 text

Traits: a simple example 9 trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird()   ! assert  b.fly()  ==  "I'm  flying!"

Slide 16

Slide 16 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'

Slide 17

Slide 17 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri' a Groovy property

Slide 18

Slide 18 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri' implement the trait

Slide 19

Slide 19 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri' Groovy named argument constructor

Slide 20

Slide 20 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri' access the property

Slide 21

Slide 21 text

Traits: stateful 10 trait  Named  {          String  name   }   ! class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'

Slide 22

Slide 22 text

Traits: inheritance 11 trait  Named  {  String  name  }   ! trait  FlyingAbility  extends  Named  {          String  fly()  {  "I'm  a  flying  ${name}!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'   assert  b.fly()  ==  "I'm  a  flying  Colibri!"

Slide 23

Slide 23 text

Traits: inheritance 11 trait  Named  {  String  name  }   ! trait  FlyingAbility  extends  Named  {          String  fly()  {  "I'm  a  flying  ${name}!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'   assert  b.fly()  ==  "I'm  a  flying  Colibri!" extend the Named trait

Slide 24

Slide 24 text

Traits: inheritance 11 trait  Named  {  String  name  }   ! trait  FlyingAbility  extends  Named  {          String  fly()  {  "I'm  a  flying  ${name}!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'   assert  b.fly()  ==  "I'm  a  flying  Colibri!" access the name property

Slide 25

Slide 25 text

Traits: inheritance 11 trait  Named  {  String  name  }   ! trait  FlyingAbility  extends  Named  {          String  fly()  {  "I'm  a  flying  ${name}!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'   assert  b.fly()  ==  "I'm  a  flying  Colibri!" implement the composite trait

Slide 26

Slide 26 text

Traits: inheritance 11 trait  Named  {  String  name  }   ! trait  FlyingAbility  extends  Named  {          String  fly()  {  "I'm  a  flying  ${name}!"  }   }   ! class  Bird  implements  FlyingAbility  {}   def  b  =  new  Bird(name:  'Colibri')   ! assert  b.name  ==  'Colibri'   assert  b.fly()  ==  "I'm  a  flying  Colibri!"

Slide 27

Slide 27 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web'

Slide 28

Slide 28 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web' two surf() methods

Slide 29

Slide 29 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web'

Slide 30

Slide 30 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web' extending a class and implementing the two traits

Slide 31

Slide 31 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web'

Slide 32

Slide 32 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web' last declared trait wins!

Slide 33

Slide 33 text

Traits: what about conflicts? 12 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  KiteSurfer,  WebSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'web'

Slide 34

Slide 34 text

Traits: what about conflicts? 13 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite'

Slide 35

Slide 35 text

Traits: what about conflicts? 13 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite' reverse the order!

Slide 36

Slide 36 text

Traits: what about conflicts? 13 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {}   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite'

Slide 37

Slide 37 text

Traits: what about conflicts? 14 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {          String  surf()  {  KiteSurfer.super.surf()  }   }   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite'

Slide 38

Slide 38 text

Traits: what about conflicts? 14 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {          String  surf()  {  KiteSurfer.super.surf()  }   }   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite' Be explicit! Override surf() 
 & use ‘super’

Slide 39

Slide 39 text

Traits: what about conflicts? 14 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {          String  surf()  {  KiteSurfer.super.surf()  }   }   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite' Your class method takes precedence over the traits

Slide 40

Slide 40 text

Traits: what about conflicts? 14 trait  KiteSurfer  {  String  surf()  {  'kite'  }  }   ! trait  WebSurfer    {  String  surf()  {    'web'  }  }   ! class  Person  {  String  name  }   ! class  Hipster  extends  Person                        implements  WebSurfer,  KiteSurfer  {          String  surf()  {  KiteSurfer.super.surf()  }   }   ! def  h  =  new  Hipster()   assert  h.surf()  ==  'kite'

Slide 41

Slide 41 text

trait  Named  {          String  name   }   ! class  Animal  {}   class  NamedAnimal  implements  Named  {}   ! def  na  =  new  NamedAnimal(name:  'Felix')   ! assert  na.name  ==  'Felix' Traits: runtime implementation 15

Slide 42

Slide 42 text

trait  Named  {          String  name   }   ! class  Animal  {}   class  NamedAnimal  implements  Named  {}   ! def  na  =  new  NamedAnimal(name:  'Felix')   ! assert  na.name  ==  'Felix' Traits: runtime implementation 15 Somewhat artificial to have to create an intermediary class to get named animals

Slide 43

Slide 43 text

trait  Named  {          String  name   }   ! class  Animal  {}   class  NamedAnimal  implements  Named  {}   ! def  na  =  new  NamedAnimal(name:  'Felix')   ! assert  na.name  ==  'Felix' Traits: runtime implementation 15

Slide 44

Slide 44 text

trait  Named  {          String  name   }   ! class  Animal  {}   ! ! def  na  =  new  Animal()  as  Named   na.name  =  'Felix'   assert  na.name  ==  'Felix' Traits: runtime implementation 16

Slide 45

Slide 45 text

trait  Named  {          String  name   }   ! class  Animal  {}   ! ! def  na  =  new  Animal()  as  Named   na.name  =  'Felix'   assert  na.name  ==  'Felix' Traits: runtime implementation 16 Runtime trait, 
 with Groovy’s usual coercion mechanism

Slide 46

Slide 46 text

trait  Named  {          String  name   }   ! class  Animal  {}   ! ! def  na  =  new  Animal()  as  Named   na.name  =  'Felix'   assert  na.name  ==  'Felix' Traits: runtime implementation 16

Slide 47

Slide 47 text

Traits: runtime implementation 17 trait  Named  {  String  name  }   ! trait  Quacks  {          String  quack()  {  'Quack!'  }   }   ! class  Animal  {}   ! def  na  =  new  Animal().withTraits  Named,  Quacks   na.name  =  'Daffy'   assert  na.name  ==  'Daffy'   assert  na.quack()  ==  'Quack!'

Slide 48

Slide 48 text

Traits: runtime implementation 17 trait  Named  {  String  name  }   ! trait  Quacks  {          String  quack()  {  'Quack!'  }   }   ! class  Animal  {}   ! def  na  =  new  Animal().withTraits  Named,  Quacks   na.name  =  'Daffy'   assert  na.name  ==  'Daffy'   assert  na.quack()  ==  'Quack!' Implement several traits at once, at runtime

Slide 49

Slide 49 text

Traits: runtime implementation 17 trait  Named  {  String  name  }   ! trait  Quacks  {          String  quack()  {  'Quack!'  }   }   ! class  Animal  {}   ! def  na  =  new  Animal().withTraits  Named,  Quacks   na.name  =  'Daffy'   assert  na.name  ==  'Daffy'   assert  na.quack()  ==  'Quack!'

Slide 50

Slide 50 text

@glaforge — Groovy in 2014 and beyond AST transforms

Slide 51

Slide 51 text

New: @TailRecursive 19 import  groovy.transform.TailRecursive   ! @TailRecursive   def  fact(BigInteger  n,  accu  =  1G)  {          if  (n  <  2)  accu          else  fact(n  -­‐  1,  n  *  accu)   }   ! assert  fact(1000)  >  10e2566

Slide 52

Slide 52 text

New: @TailRecursive 19 import  groovy.transform.TailRecursive   ! @TailRecursive   def  fact(BigInteger  n,  accu  =  1G)  {          if  (n  <  2)  accu          else  fact(n  -­‐  1,  n  *  accu)   }   ! assert  fact(1000)  >  10e2566 Rewrites tail recursive friendly function serially

Slide 53

Slide 53 text

New: @TailRecursive 19 import  groovy.transform.TailRecursive   ! @TailRecursive   def  fact(BigInteger  n,  accu  =  1G)  {          if  (n  <  2)  accu          else  fact(n  -­‐  1,  n  *  accu)   }   ! assert  fact(1000)  >  10e2566 Doesn’t blow up with a stack overflow error

Slide 54

Slide 54 text

New: @TailRecursive 19 import  groovy.transform.TailRecursive   ! @TailRecursive   def  fact(BigInteger  n,  accu  =  1G)  {          if  (n  <  2)  accu          else  fact(n  -­‐  1,  n  *  accu)   }   ! assert  fact(1000)  >  10e2566 Downside of tail recursion is 
 you might have to rewrite 
 your algo to be tailrec friendly

Slide 55

Slide 55 text

New: @TailRecursive 19 import  groovy.transform.TailRecursive   ! @TailRecursive   def  fact(BigInteger  n,  accu  =  1G)  {          if  (n  <  2)  accu          else  fact(n  -­‐  1,  n  *  accu)   }   ! assert  fact(1000)  >  10e2566

Slide 56

Slide 56 text

New: @Sortable 20 import  groovy.transform.*   ! @Sortable   class  Person  {          String  lastName          String  firstName          int  age   }

Slide 57

Slide 57 text

New: @Sortable 20 import  groovy.transform.*   ! @Sortable   class  Person  {          String  lastName          String  firstName          int  age   } Makes the class Comparable by multiple Comparators

Slide 58

Slide 58 text

New: @Sortable 20 import  groovy.transform.*   ! @Sortable   class  Person  {          String  lastName          String  firstName          int  age   } First compare by lastName, then by firstName, etc.

Slide 59

Slide 59 text

New: @Sortable 20 import  groovy.transform.*   ! @Sortable   class  Person  {          String  lastName          String  firstName          int  age   } You can also specify ‘includes’ / ‘excludes’ properties

Slide 60

Slide 60 text

New: @Sortable 20 import  groovy.transform.*   ! @Sortable   class  Person  {          String  lastName          String  firstName          int  age   }

Slide 61

Slide 61 text

@BaseScript improvements 21 abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   ! assert  meaningOfLife  ==  42

Slide 62

Slide 62 text

@BaseScript improvements 21 abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   ! assert  meaningOfLife  ==  42 You can add your own base methods and properties to all compiled scripts

Slide 63

Slide 63 text

@BaseScript improvements 21 abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   ! assert  meaningOfLife  ==  42 Define the base script class for this script

Slide 64

Slide 64 text

@BaseScript improvements 21 abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   ! assert  meaningOfLife  ==  42 Ability to put the annotation on imports & package

Slide 65

Slide 65 text

@BaseScript improvements 21 abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   ! assert  meaningOfLife  ==  42

Slide 66

Slide 66 text

@BaseScript custom abstract method 22 abstract  class  CustomBase  extends  Script  {      def  run()  {          before()          internalRun()          after()      }   !    abstract  internalRun()   !    def  before()  {  println  'before'  }      def  after()    {  println  'after'    }   }

Slide 67

Slide 67 text

@BaseScript custom abstract method 22 abstract  class  CustomBase  extends  Script  {      def  run()  {          before()          internalRun()          after()      }   !    abstract  internalRun()   !    def  before()  {  println  'before'  }      def  after()    {  println  'after'    }   } import  groovy.transform.BaseScript   @BaseScript  CustomBase  script   ! println  'Hello'

Slide 68

Slide 68 text

@BaseScript custom abstract method 22 abstract  class  CustomBase  extends  Script  {      def  run()  {          before()          internalRun()          after()      }   !    abstract  internalRun()   !    def  before()  {  println  'before'  }      def  after()    {  println  'after'    }   } import  groovy.transform.BaseScript   @BaseScript  CustomBase  script   ! println  'Hello' You can define your own abstract method for script bodies

Slide 69

Slide 69 text

@BaseScript custom abstract method 22 abstract  class  CustomBase  extends  Script  {      def  run()  {          before()          internalRun()          after()      }   !    abstract  internalRun()   !    def  before()  {  println  'before'  }      def  after()    {  println  'after'    }   } import  groovy.transform.BaseScript   @BaseScript  CustomBase  script   ! println  'Hello'

Slide 70

Slide 70 text

@glaforge — Groovy in 2014 and beyond NIO2 module

Slide 71

Slide 71 text

JDK 7+ NIO2 module • All the familiar methods on File 
 retrofitted on Path as well 24 path.withReader  {  Reader  r  -­‐>  ...  }   path.eachLine  {  String  line  -­‐>  ...  }   path.eachFileRecurse  {  Path  p  -­‐>  ...  }   path  <<  'some  content'   path  <<  bytes   path.readLines()   …

Slide 72

Slide 72 text

JDK 7+ NIO2 module • All the familiar methods on File 
 retrofitted on Path as well 24 path.withReader  {  Reader  r  -­‐>  ...  }   path.eachLine  {  String  line  -­‐>  ...  }   path.eachFileRecurse  {  Path  p  -­‐>  ...  }   path  <<  'some  content'   path  <<  bytes   path.readLines()   … Feature request to add all the java.nio.file.Files static utility methods as GDK

Slide 73

Slide 73 text

JDK 7+ NIO2 module • All the familiar methods on File 
 retrofitted on Path as well 24 path.withReader  {  Reader  r  -­‐>  ...  }   path.eachLine  {  String  line  -­‐>  ...  }   path.eachFileRecurse  {  Path  p  -­‐>  ...  }   path  <<  'some  content'   path  <<  bytes   path.readLines()   …

Slide 74

Slide 74 text

@glaforge — Groovy in 2014 and beyond JSON

Slide 75

Slide 75 text

JSON parser / builder perf. increase • Re-implementation of JSON support for speed & efficiency • parser forked off the Boon JSON project • serializer carefully fine-tuned ! • Article on the parsing speed improvements • http://rick-hightower.blogspot.fr/2014/04/groovy-and-boon-provide-fastest-json.html 26

Slide 76

Slide 76 text

JSON parser / builder perf. increase • Re-implementation of JSON support for speed & efficiency • parser forked off the Boon JSON project • serializer carefully fine-tuned ! • Article on the parsing speed improvements • http://rick-hightower.blogspot.fr/2014/04/groovy-and-boon-provide-fastest-json.html 26

Slide 77

Slide 77 text

JSON parser / builder perf. increase • Re-implementation of JSON support for speed & efficiency • parser forked off the Boon JSON project • serializer carefully fine-tuned ! • Article on the parsing speed improvements • http://rick-hightower.blogspot.fr/2014/04/groovy-and-boon-provide-fastest-json.html 26 Benchmark gives 3x to 4x performance factor 
 over Jackson and GSON

Slide 78

Slide 78 text

JSON parser / builder perf. increase • Re-implementation of JSON support for speed & efficiency • parser forked off the Boon JSON project • serializer carefully fine-tuned ! • Article on the parsing speed improvements • http://rick-hightower.blogspot.fr/2014/04/groovy-and-boon-provide-fastest-json.html 26

Slide 79

Slide 79 text

New modes for parsing • Original JsonSlurper renamed to JsonSlurperClassic ! • Additional parsing modes: • INDEX_OVERLAY: super fast for <2MB payloads o using a « parsing overlay » technique • CHARACTER_SOURCE: for >2MB payloads o implemented with sliding windows over readers • LAX: beyond the JSON spec, nice for configuration files o support single quotes, / and # comments • CHAR_BUFFER: general purpose 27

Slide 80

Slide 80 text

JsonSlurper for configuration files 28 import  groovy.json.*   import  static  groovy.json.JsonParserType.*   ! def  parser  =  new  JsonSlurper().setType(LAX)   ! def  conf  =  parser.parseText  '''          //  configuration  file          {                  //  no  quote  for  key,  single  quoted  value                  environment:  'production'                  #  pound-­‐style  comment                  'server':  5          }   '''   ! assert  conf.environment  ==  'production'   assert  conf.server  ==  5

Slide 81

Slide 81 text

JsonSlurper for configuration files 28 import  groovy.json.*   import  static  groovy.json.JsonParserType.*   ! def  parser  =  new  JsonSlurper().setType(LAX)   ! def  conf  =  parser.parseText  '''          //  configuration  file          {                  //  no  quote  for  key,  single  quoted  value                  environment:  'production'                  #  pound-­‐style  comment                  'server':  5          }   '''   ! assert  conf.environment  ==  'production'   assert  conf.server  ==  5 More tolerant parser: 
 single quotes, 
 non-quoted keys, 
 // and # comments, missing comas

Slide 82

Slide 82 text

JsonSlurper for configuration files 28 import  groovy.json.*   import  static  groovy.json.JsonParserType.*   ! def  parser  =  new  JsonSlurper().setType(LAX)   ! def  conf  =  parser.parseText  '''          //  configuration  file          {                  //  no  quote  for  key,  single  quoted  value                  environment:  'production'                  #  pound-­‐style  comment                  'server':  5          }   '''   ! assert  conf.environment  ==  'production'   assert  conf.server  ==  5

Slide 83

Slide 83 text

@glaforge — Groovy in 2014 and beyond Markup template engine

Slide 84

Slide 84 text

Markup template engine • Based on the principles of Groovy’s « builders » • and particularly the MarkupBuilder class
 for generating arbitrary XML / HTML payloads ! • Compiled statically for fast template rendering ! • Internationalization aware • provide the desired Locale in the configuration object • usual suffix notation template_fr_FR.tpl ! • Custom base template class • ability to provide reusable methods across your templates 30

Slide 85

Slide 85 text

Markup template engine • Based on the principles of Groovy’s « builders » • and particularly the MarkupBuilder class
 for generating arbitrary XML / HTML payloads ! • Compiled statically for fast template rendering ! • Internationalization aware • provide the desired Locale in the configuration object • usual suffix notation template_fr_FR.tpl ! • Custom base template class • ability to provide reusable methods across your templates 30 Spring Boot approved

Slide 86

Slide 86 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   }

Slide 87

Slide 87 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } Your template

Slide 88

Slide 88 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)! ]]

Slide 89

Slide 89 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)! ]] Feed a model into your template

Slide 90

Slide 90 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)! ]] ! ! !

Slide 91

Slide 91 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)! ]] ! ! ! Generate the XML output

Slide 92

Slide 92 text

Markup template engine — the idea 31 cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)! ]] ! ! !

Slide 93

Slide 93 text

Markup template engine — in action 32 import  groovy.text.markup.*   ! def  config  =  new  TemplateConfiguration()   def  engine  =  new  MarkupTemplateEngine(config)   def  tmpl  =  engine.createTemplate('''          p("Hello  ${model.name}")   ''')   def  model  =  [name:  'World']   System.out  <<  tmpl.make(model)

Slide 94

Slide 94 text

Markup template engine — includes 33 //  include  another  template   include  template:  'foo.tpl'           //  include  raw  content   include  unescaped:  'raw.txt'   ! //  escape  &  include   include  escaped:  'to_escape.txt'

Slide 95

Slide 95 text

Markup template engine — static! • Type-checked templates available • use createTypeCheckedModelTemplate() 
 instead of createTemplate() ! • Advantages • get compilation errors o if a variable is not available o if you make mistakes in the code snippets • even faster templates 34

Slide 96

Slide 96 text

Markup template engine — static! • With typed check model creation method ! ! ! ! ! ! ! ! ! • Or declare your model types in the template 35

Slide 97

Slide 97 text

Markup template engine — static! • With typed check model creation method ! ! ! ! ! ! ! ! ! • Or declare your model types in the template 35 def  modelTypes  =  [cars:  "List"]   ! def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes)

Slide 98

Slide 98 text

Markup template engine — static! • With typed check model creation method ! ! ! ! ! ! ! ! ! • Or declare your model types in the template 35 def  modelTypes  =  [cars:  "List"]   ! def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List  cars   }   ! cars.each  {  car  -­‐>          p("Car  name:  $car.name")   }

Slide 99

Slide 99 text

Markup template engine — static! • With typed check model creation method ! ! ! ! ! ! ! ! ! • Or declare your model types in the template 35 def  modelTypes  =  [cars:  "List"]   ! def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List  cars   }   ! cars.each  {  car  -­‐>          p("Car  name:  $car.name")   } Works with createTemplate() too

Slide 100

Slide 100 text

Markup template engine — static! • With typed check model creation method ! ! ! ! ! ! ! ! ! • Or declare your model types in the template 35 def  modelTypes  =  [cars:  "List"]   ! def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List  cars   }   ! cars.each  {  car  -­‐>          p("Car  name:  $car.name")   }

Slide 101

Slide 101 text

@glaforge — Groovy in 2014 and beyond Documentation overhaul

Slide 102

Slide 102 text

GroovyDoc 37

Slide 103

Slide 103 text

GroovyDoc 37

Slide 104

Slide 104 text

GroovyDoc 37

Slide 105

Slide 105 text

Groovy GDK documentation 38

Slide 106

Slide 106 text

Groovy GDK documentation 38

Slide 107

Slide 107 text

Brand new documentation 39

Slide 108

Slide 108 text

@glaforge — Groovy in 2014 and beyond Groovy 2.4

Slide 109

Slide 109 text

Beta groovy-lang.org website 41

Slide 110

Slide 110 text

Beta groovy-lang.org website 41

Slide 111

Slide 111 text

Beta groovy-lang.org website 41

Slide 112

Slide 112 text

Beta groovy-lang.org website 41 Notice the « improve this doc » button!

Slide 113

Slide 113 text

Android support • You can use Groovy to code Android apps! • use Groovy 2.4.0-beta-1+ • prefer @CompileStatic ! • Two great posts to get started: • http://melix.github.io/blog/2014/06/grooid.html • http://melix.github.io/blog/2014/06/grooid2.html 42

Slide 114

Slide 114 text

New York Times — Getting Groovy with Android • New York Times Getting Groovy with Reactive Android 43

Slide 115

Slide 115 text

New York Times — Getting Groovy with Android • New York Times Getting Groovy with Reactive Android 43 http://bit.ly/nyt-groovy

Slide 116

Slide 116 text

Android support 44

Slide 117

Slide 117 text

Android support 44 Source code available: https://github.com/melix/gr8confagenda

Slide 118

Slide 118 text

Groovy Macros ! • Sergei Egorov wants to contribute a macro module • https://github.com/groovy/groovy-core/pull/470 ! • Simplify creation of AST transformations • less boilerplate manipulating the Groovy AST API • more powerful and less limited than AstBuilder 45

Slide 119

Slide 119 text

Groovy Macros ! • Authoring AST transformations can be verbose: 46 def  someVariable  =  new  ConstantExpression("xyz")   def  returnStatement  =  new  ReturnStatement(          new  ConstructorCallExpression(                  ClassHelper.make(SomeCoolClass),                  new  ArgumentListExpression(someVariable)          )   )

Slide 120

Slide 120 text

Groovy Macros • With Groovy Macros, it could be simpler: 47 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     }

Slide 121

Slide 121 text

Groovy Macros • With Groovy Macros, it could be simpler: 47 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     } Special « macro » command

Slide 122

Slide 122 text

Groovy Macros • With Groovy Macros, it could be simpler: 47 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     } Special « macro » command Quasi-quotation

Slide 123

Slide 123 text

@glaforge — Groovy in 2014 and beyond Groovy 3.0

Slide 124

Slide 124 text

No content

Slide 125

Slide 125 text

@glaforge — Groovy in 2014 and beyond New Age Meta-Object Protocol MOP 2

Slide 126

Slide 126 text

Goals for the new MOP • Leverage & build upon JDK 7+ invoke dynamic • get Java-like performance even for dynamic code • Rationalize the sedimentation of meta-programming • more coherence, less corner cases & inconsistencies • Provide a notion of « realm » • shield users of « monkey patching » • finer-grained control of meta-programming reach • Private visibility anyone? 51

Slide 127

Slide 127 text

@glaforge — Groovy in 2014 and beyond Rewriting the Groovy grammar with Antlr v4 Antlr v4 Grammar

Slide 128

Slide 128 text

Antlr v4 grammar • Problems • Groovy still uses Antlr v2! o but version 3 and 4 are out • Groovy’s grammar evolved from a Java grammar o harder to fix and evolve, especially with Antlr v2 • Advantages • Start from a clean slate • Antlr 4 more tolerant 
 and powerful regarding ambiguities • Time to clean some grammar & syntax warts! • Need to implement the Java 8 constructs! 53

Slide 129

Slide 129 text

Antlr v4 grammar • Problems • Groovy still uses Antlr v2! o but version 3 and 4 are out • Groovy’s grammar evolved from a Java grammar o harder to fix and evolve, especially with Antlr v2 • Advantages • Start from a clean slate • Antlr 4 more tolerant 
 and powerful regarding ambiguities • Time to clean some grammar & syntax warts! • Need to implement the Java 8 constructs! 53 A « Google Summer of Code » student helped kick start it

Slide 130

Slide 130 text

@glaforge — Groovy in 2014 and beyond Support the new Java 8 language features Java 8 language support

Slide 131

Slide 131 text

Java 8 support • Additional grammar & semantic features to support • to keep saying Groovy / Java interoperability is awesome! • New in Java 8 • lambdas • method references • default methods in interfaces • stream API, date / time API • annotations on types & repeated annotations 55

Slide 132

Slide 132 text

Java 8 support • Additional grammar & semantic features to support • to keep saying Groovy / Java interoperability is awesome! • New in Java 8 • lambdas • method references • default methods in interfaces • stream API, date / time API • annotations on types & repeated annotations 55 Groovy had already: closures, method pointers, mixins, enriched collection & time APIs

Slide 133

Slide 133 text

@glaforge — Groovy in 2014 and beyond Summary

Slide 134

Slide 134 text

No content

Slide 135

Slide 135 text

Groovy rocks the JVM 
 since 2003!

Slide 136

Slide 136 text

@glaforge — Groovy in 2014 and beyond Q & A

Slide 137

Slide 137 text

No content

Slide 138

Slide 138 text

Image credits • Big rock • http://wallpaper.preview-reviews.com/12852-red-rocks-in-a-snowstorm • Android robot • http://crackberry.com/sites/crackberry.com/files/styles/large/public/topic_images/2013/ANDROID.png?itok=xhm7jaxS • Modern MOP • http://i933.photobucket.com/albums/ad179/autobin/Wonder%20Mop/wondermop4.jpg • Jason • http://static.comicvine.com/uploads/original/3/32405/1031312-jason_19_inch_figure_l.jpg • Jigsaw • http://www.psdgraphics.com/file/psd-jigsaw-icon.jpg • Many thanks • http://www.trys.ie/wp-content/uploads/2013/06/many-thanks.jpg 60