Groovy in 2014 and beyond -- Groovy Grails eXchange 2014

Groovy in 2014 and beyond -- Groovy Grails eXchange 2014

As usual, Guillaume Laforge will go through the latest developments of the Groovy programming language and will update you with what's going on, what's to come, and beyond the language itself.

137d3908243acfc30e126615d59d4e6d?s=128

Guillaume Laforge

December 11, 2014
Tweet

Transcript

  1. @glaforge #groovylang Groovy in 2014 & beyond Guillaume Laforge Groovy

    project manager
  2. #groovylang @glaforge Stay up-to-date Groovy Weekly newsletter (every Tuesday) 


    http://beta.groovy-lang.org/groovy-weekly.html 2
  3. #groovylang @glaforge The Groovy roadmap 3 2015 2014 2013 Groovy

    2.3 Groovy 2.4 Groovy 2.2 Groovy 2.5 Groovy 3.0 ?
  4. @glaforge #groovylang Groovy 2.3

  5. @glaforge #groovylang JDK 8 support

  6. #groovylang @glaforge 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));
  7. #groovylang @glaforge 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  }
  8. #groovylang @glaforge 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
  9. @glaforge #groovylang Traits

  10. #groovylang @glaforge 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
  11. #groovylang @glaforge 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!"
  12. #groovylang @glaforge 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
  13. #groovylang @glaforge 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
  14. #groovylang @glaforge 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
  15. #groovylang @glaforge 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!"
  16. #groovylang @glaforge Traits: stateful 10 trait  Named  {    

         String  name   }   class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   assert  b.name  ==  'Colibri'
  17. #groovylang @glaforge Traits: stateful 10 trait  Named  {    

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

         String  name   }   class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   assert  b.name  ==  'Colibri' implement the trait
  19. #groovylang @glaforge 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
  20. #groovylang @glaforge Traits: stateful 10 trait  Named  {    

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

         String  name   }   class  Bird  implements  Named  {}   def  b  =  new  Bird(name:  'Colibri')   assert  b.name  ==  'Colibri'
  22. #groovylang @glaforge 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!"
  23. #groovylang @glaforge 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
  24. #groovylang @glaforge 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
  25. #groovylang @glaforge 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
  26. #groovylang @glaforge 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!"
  27. #groovylang @glaforge 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'
  28. #groovylang @glaforge 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
  29. #groovylang @glaforge 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'
  30. #groovylang @glaforge 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
  31. #groovylang @glaforge 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'
  32. #groovylang @glaforge 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!
  33. #groovylang @glaforge 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'
  34. #groovylang @glaforge 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'
  35. #groovylang @glaforge 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!
  36. #groovylang @glaforge 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'
  37. #groovylang @glaforge 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'
  38. #groovylang @glaforge 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’
  39. #groovylang @glaforge 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
  40. #groovylang @glaforge 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'
  41. #groovylang @glaforge Traits: runtime implementation 15 trait  Named  {  

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

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

           String  name   }   class  Animal  {}   class  NamedAnimal  implements  Named  {}   def  na  =  new  NamedAnimal(name:  'Felix')   assert  na.name  ==  'Felix'
  44. #groovylang @glaforge Traits: runtime implementation 16 trait  Named  {  

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

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

           String  name   }   class  Animal  {}   def  na  =  new  Animal()  as  Named   na.name  =  'Felix'   assert  na.name  ==  'Felix'
  47. #groovylang @glaforge 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!'
  48. #groovylang @glaforge 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
  49. #groovylang @glaforge 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!'
  50. @glaforge #groovylang AST transforms

  51. #groovylang @glaforge 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
  52. #groovylang @glaforge 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
  53. #groovylang @glaforge 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
  54. #groovylang @glaforge 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
  55. #groovylang @glaforge 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
  56. #groovylang @glaforge New: @Sortable 20 import  groovy.transform.*   @Sortable  

    class  Person  {          String  lastName          String  firstName          int  age   }
  57. #groovylang @glaforge New: @Sortable 20 import  groovy.transform.*   @Sortable  

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

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

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

    class  Person  {          String  lastName          String  firstName          int  age   }
  61. #groovylang @glaforge New: @Builder for fluent APIs 21 import  groovy.transform.builder.Builder


    
 @Builder
 class  Person  {
    String  firstName
    String  lastName
    int  age
 }
  62. #groovylang @glaforge New: @Builder for fluent APIs 21 import  groovy.transform.builder.Builder


    
 @Builder
 class  Person  {
    String  firstName
    String  lastName
    int  age
 } def  person  =  Person.builder()
                .firstName("Robert")
                .lastName("Lewandowski")
                .age(21)
                .build()
  63. #groovylang @glaforge New: @Builder for fluent APIs 21 import  groovy.transform.builder.Builder


    
 @Builder
 class  Person  {
    String  firstName
    String  lastName
    int  age
 } def  person  =  Person.builder()
                .firstName("Robert")
                .lastName("Lewandowski")
                .age(21)
                .build() Different implementation strategies available
  64. #groovylang @glaforge New: @Builder for fluent APIs 21 import  groovy.transform.builder.Builder


    
 @Builder
 class  Person  {
    String  firstName
    String  lastName
    int  age
 } def  person  =  Person.builder()
                .firstName("Robert")
                .lastName("Lewandowski")
                .age(21)
                .build()
  65. #groovylang @glaforge @BaseScript improvements 22 abstract  class  CustomBase  extends  Script

     {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   assert  meaningOfLife  ==  42
  66. #groovylang @glaforge @BaseScript improvements 22 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
  67. #groovylang @glaforge @BaseScript improvements 22 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
  68. #groovylang @glaforge @BaseScript improvements 22 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
  69. #groovylang @glaforge @BaseScript improvements 22 abstract  class  CustomBase  extends  Script

     {          int  meaningOfLife  =  42   } @BaseScript(CustomBase)   import  groovy.transform.BaseScript   assert  meaningOfLife  ==  42
  70. #groovylang @glaforge @BaseScript custom abstract method 23 abstract  class  CustomBase

     extends  Script  {      def  run()  {          before()          internalRun()          after()      }      abstract  internalRun()      def  before()  {  println  'before'  }      def  after()    {  println  'after'    }   }
  71. #groovylang @glaforge @BaseScript custom abstract method 23 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'
  72. #groovylang @glaforge @BaseScript custom abstract method 23 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
  73. #groovylang @glaforge @BaseScript custom abstract method 23 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'
  74. @glaforge #groovylang NIO2 module

  75. #groovylang @glaforge JDK 7+ NIO2 module • All the familiar

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

    methods on File 
 retrofitted on Path as well 25 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
  77. #groovylang @glaforge JDK 7+ NIO2 module • All the familiar

    methods on File 
 retrofitted on Path as well 25 path.withReader  {  Reader  r  -­‐>  ...  }   path.eachLine  {  String  line  -­‐>  ...  }   path.eachFileRecurse  {  Path  p  -­‐>  ...  }   path  <<  'some  content'   path  <<  bytes   path.readLines()   …
  78. @glaforge #groovylang JSON

  79. #groovylang @glaforge 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 27
  80. #groovylang @glaforge 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 27
  81. #groovylang @glaforge 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 27 Benchmark gives 3x to 4x performance factor 
 over Jackson and GSON
  82. #groovylang @glaforge 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 27
  83. #groovylang @glaforge New modes for parsing • Original JsonSlurper renamed

    to JsonSlurperClassic • Additional parsing modes: • INDEX_OVERLAY: super fast for <2MB payloads • using a « parsing overlay » technique • CHARACTER_SOURCE: for >2MB payloads • implemented with sliding windows over readers • LAX: beyond the JSON spec, nice for configuration files • support single quotes, / and # comments • CHAR_BUFFER: general purpose 28
  84. #groovylang @glaforge JsonSlurper for configuration files 29 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
  85. #groovylang @glaforge JsonSlurper for configuration files 29 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
  86. #groovylang @glaforge JsonSlurper for configuration files 29 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
  87. @glaforge #groovylang Markup template engine </>

  88. #groovylang @glaforge 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 31
  89. #groovylang @glaforge 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 31 Spring Boot approved
  90. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   }
  91. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } Your template
  92. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [ new Car(make: 'Peugeot', name: '508'), new Car(make: 'Toyota', name: 'Prius’) ]]
  93. #groovylang @glaforge Markup template engine — the idea 32 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
  94. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [ new Car(make: 'Peugeot', name: '508'), new Car(make: 'Toyota', name: 'Prius’) ]] <cars> <car make='Peugeot' name='508'/> <car make='Toyota' name='Prius'/> </cars>
  95. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [ new Car(make: 'Peugeot', name: '508'), new Car(make: 'Toyota', name: 'Prius’) ]] <cars> <car make='Peugeot' name='508'/> <car make='Toyota' name='Prius'/> </cars> Generate the XML output
  96. #groovylang @glaforge Markup template engine — the idea 32 cars

     {        cars.each  {                car(make:  it.make,  name:  it.name)        }   } model = [cars: [ new Car(make: 'Peugeot', name: '508'), new Car(make: 'Toyota', name: 'Prius’) ]] <cars> <car make='Peugeot' name='508'/> <car make='Toyota' name='Prius'/> </cars>
  97. #groovylang @glaforge Markup template engine — in action 33 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)
  98. #groovylang @glaforge Markup template engine — includes 34 //  include

     another  template   include  template:  'foo.tpl'           //  include  raw  content   include  unescaped:  'raw.txt'   //  escape  &  include   include  escaped:  'to_escape.txt'
  99. #groovylang @glaforge Markup template engine — static! • Type-checked templates

    available • use createTypeCheckedModelTemplate() 
 instead of createTemplate() • Advantages • get compilation errors • if a variable is not available • if you make mistakes in the code snippets • even faster templates 35
  100. #groovylang @glaforge Markup template engine — static! • With typed

    checked model creation method 36
  101. #groovylang @glaforge Markup template engine — static! • With typed

    checked model creation method 36 def  modelTypes  =  [cars:  "List<Car>"]   def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes)
  102. #groovylang @glaforge Markup template engine — static! • With typed

    checked model creation method 36 def  modelTypes  =  [cars:  "List<Car>"]   def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List<Car>  cars   }   cars.each  {  car  -­‐>          p("Car  name:  $car.name")   }
  103. #groovylang @glaforge Markup template engine — static! • With typed

    checked model creation method 36 def  modelTypes  =  [cars:  "List<Car>"]   def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List<Car>  cars   }   cars.each  {  car  -­‐>          p("Car  name:  $car.name")   } Works with createTemplate() too
  104. #groovylang @glaforge Markup template engine — static! • With typed

    checked model creation method 36 def  modelTypes  =  [cars:  "List<Car>"]   def  tmpl  =  engine.      createTypeCheckedModelTemplate(
            "page.tpl",  modelTypes) modelTypes  =  {          List<Car>  cars   }   cars.each  {  car  -­‐>          p("Car  name:  $car.name")   }
  105. @glaforge #groovylang Documentation overhaul

  106. #groovylang @glaforge GroovyDoc 38

  107. #groovylang @glaforge GroovyDoc 38

  108. #groovylang @glaforge GroovyDoc 38

  109. #groovylang @glaforge Groovy GDK documentation 39

  110. #groovylang @glaforge Groovy GDK documentation 39

  111. #groovylang @glaforge Brand new documentation 40

  112. @glaforge #groovylang Groovy 2.4

  113. #groovylang @glaforge Beta groovy-lang.org website 42

  114. #groovylang @glaforge Beta groovy-lang.org website 42

  115. #groovylang @glaforge Beta groovy-lang.org website 42

  116. #groovylang @glaforge Beta groovy-lang.org website 42 Notice the « improve

    this doc » button!
  117. #groovylang @glaforge 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 43
  118. #groovylang @glaforge New York Times — Getting Groovy with 44

  119. #groovylang @glaforge New York Times — Getting Groovy with 44

    http://bit.ly/nyt-groovy
  120. #groovylang @glaforge Android support 45

  121. #groovylang @glaforge Android support 45 Source code available: https://github.com/melix/gr8confagenda

  122. #groovylang @glaforge Type constraints on traits with @SelfType • Only

    apply a trait to some child classes 46 class  Component  {
        void  doSomething()  {}
 }
 
 @SelfType(Component)
 trait  ComponentDecorator  {
        void  logAndDoSomething()  {
                println  "Calling  doSomething()"
                doSomething()
        }
 }
  123. #groovylang @glaforge StreamingTemplateEngine • Uses writable closures to stream the

    output • Works with templates bigger than 64K 47 import  groovy.text.*   def  eng  =  new  StreamingTemplateEngine()   def  tpl  =  eng.createTemplate  '''
        Hi  ${name}
 '''   println  tpl.make(name:  'Guillaume')
  124. @glaforge #groovylang Groovy 2.5

  125. #groovylang @glaforge 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 49
  126. #groovylang @glaforge Groovy Macros • Authoring AST transformations can be

    verbose: 50 def  someVariable  =  new  ConstantExpression("xyz")   def  returnStatement  =  new  ReturnStatement(          new  ConstructorCallExpression(                  ClassHelper.make(SomeCoolClass),                  new  ArgumentListExpression(someVariable)          )   )
  127. #groovylang @glaforge Groovy Macros • With Groovy Macros, it could

    be simpler: 51 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     }
  128. #groovylang @glaforge Groovy Macros • With Groovy Macros, it could

    be simpler: 51 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     } Special « macro » command
  129. #groovylang @glaforge Groovy Macros • With Groovy Macros, it could

    be simpler: 51 def  someVariable  =  macro  {  "xyz"  }   def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })     } Special « macro » command Quasi-quotation
  130. @glaforge #groovylang Groovy 3.0

  131. None
  132. @glaforge #groovylang Rewriting the Groovy grammar with Antlr v4 Antlr

    v4 Grammar
  133. #groovylang @glaforge Antlr v4 grammar • Problems • Groovy still

    uses Antlr v2! • but version 3 and 4 are out • Groovy’s grammar evolved from a Java grammar • 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! 55
  134. #groovylang @glaforge Antlr v4 grammar • Problems • Groovy still

    uses Antlr v2! • but version 3 and 4 are out • Groovy’s grammar evolved from a Java grammar • 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! 55 A « Google Summer of Code » student helped kick start it
  135. @glaforge #groovylang Java 8 language support

  136. #groovylang @glaforge 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 57
  137. #groovylang @glaforge 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 57 Groovy had already: closures, method pointers, mixins, enriched collection & time APIs
  138. @glaforge #groovylang MOP 2

  139. #groovylang @glaforge 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? 59
  140. @glaforge #groovylang Summary

  141. None
  142. Groovy rocks the JVM 
 since 2003!

  143. @glaforge #groovylang Q & A

  144. None
  145. #groovylang @glaforge Image credits • London: • http://www.excel-london.co.uk/media/26705/why-london-hero-shot.jpg • http://libertychurchlondon.com/wp-content/uploads/2013/01/london1.jpg

    • http://cdni.wired.co.uk/1920x1280/k_n/London_5.jpg • http://www.100percentoptical.com/images/2014/10/london.jpg • 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 64