Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Groovy in 2014 and beyond at Devoxx France

Groovy in 2014 and beyond at Devoxx France

New presentation on all the new features of Groovy 2.3

Guillaume Laforge

April 18, 2014
Tweet

More Decks by Guillaume Laforge

Other Decks in Technology

Transcript

  1. @glaforge
    #dvxgroovy
    Groovy en 2014 et au-delà…
    Guillaume Laforge
    Groovy Project Manager
    http://glaforge.appspot.com

    View Slide

  2. View Slide

  3. Les Cast
    Codeurs

    View Slide

  4. Les Cast
    Codeurs
    18:05
    Miles Davis

    View Slide

  5. @glaforge
    #dvxgroovy
    Stay up-to-date with all things Groovy
    !
    • Groovy Weekly newsletter
    • Every Tuesday

    !
    • http://bit.ly/groovy-weekly-
    subscribe

    View Slide

  6. @glaforge
    #dvxgroovy
    Stay up-to-date with all things Groovy
    !
    • Groovy Google+ page
    !
    • https://plus.google.com/
    +groovy

    View Slide

  7. @glaforge
    #dvxgroovy
    Stay up-to-date with all things Groovy
    !
    • Groovy Google+
    community
    !
    • https://plus.google.com/
    communities/
    105160926044623621768

    View Slide

  8. @YourTwitterHandle
    #DVXFR14{session hashtag} @glaforge
    #dvxgroovy
    A
    genda

    View Slide

  9. @glaforge
    #dvxgroovy
    The Groovy roadmap…
    2015
    2014
    2013

    View Slide

  10. @glaforge
    #dvxgroovy
    The Groovy roadmap…
    2015
    2014
    2013
    Groovy 2.2

    View Slide

  11. @glaforge
    #dvxgroovy
    The Groovy roadmap…
    2015
    2014
    2013
    Groovy 2.3
    Groovy 2.2

    View Slide

  12. @glaforge
    #dvxgroovy
    The Groovy roadmap…
    2015
    2014
    2013
    Groovy 2.3
    Groovy 3.0
    Groovy 2.2

    View Slide

  13. @glaforge
    #dvxgroovy
    Groovy 2.3
    • JDK 8 runtime support

    • Traits

    • New and updates AST transformations

    • NIO2 module

    • JSON improvements & performance gains

    • New Markup template engine

    • Documentation overhaul

    View Slide

  14. @glaforge
    #dvxgroovy
    Groovy 3.0
    !
    • New Meta-Object Protocol

    !
    • Invoke-dynamic based runtime

    !
    • Rewritten language grammar with Antlr v4

    View Slide

  15. @YourTwitterHandle
    #DVXFR14{session hashtag} @glaforge
    #dvxgroovy
    G
    roovy
    2.3

    View Slide

  16. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    JD
    K
    8
    support

    View Slide

  17. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    Traits

    View Slide

  18. @glaforge
    #dvxgroovy
    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 & compilation

    • class methods coming from traits are also visible from Java

    • Also possible to implement traits at runtime

    View Slide

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

    View Slide

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

    View Slide

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

    « implements »

    a trait

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. @glaforge
    #dvxgroovy
    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!"
    Traits: inheritance

    View Slide

  31. @glaforge
    #dvxgroovy
    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!"
    Traits: inheritance
    extend the Named trait

    View Slide

  32. @glaforge
    #dvxgroovy
    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!"
    Traits: inheritance
    access the name property

    View Slide

  33. @glaforge
    #dvxgroovy
    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!"
    Traits: inheritance
    implement the composite trait

    View Slide

  34. @glaforge
    #dvxgroovy
    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!"
    Traits: inheritance

    View Slide

  35. @glaforge
    #dvxgroovy
    trait  FlyingAbility  {  
           String  fly()  {  "I'm  a  flying  $name!"  }  
    }  
    !
    trait  Named  {  String  name  }  
    !
    class  Bird  implements  Named,  FlyingAbility  {}  
    def  b  =  new  Bird(name:  'Colibri')  
    !
    assert  b.name  ==  'Colibri'  
    assert  b.fly()  ==  "I'm  a  flying  Colibri!"
    Traits: multiple inheritance (& dynamism)

    View Slide

  36. @glaforge
    #dvxgroovy
    trait  FlyingAbility  {  
           String  fly()  {  "I'm  a  flying  $name!"  }  
    }  
    !
    trait  Named  {  String  name  }  
    !
    class  Bird  implements  Named,  FlyingAbility  {}  
    def  b  =  new  Bird(name:  'Colibri')  
    !
    assert  b.name  ==  'Colibri'  
    assert  b.fly()  ==  "I'm  a  flying  Colibri!"
    Traits: multiple inheritance (& dynamism)
    access a dynamic property

    View Slide

  37. @glaforge
    #dvxgroovy
    trait  FlyingAbility  {  
           String  fly()  {  "I'm  a  flying  $name!"  }  
    }  
    !
    trait  Named  {  String  name  }  
    !
    class  Bird  implements  Named,  FlyingAbility  {}  
    def  b  =  new  Bird(name:  'Colibri')  
    !
    assert  b.name  ==  'Colibri'  
    assert  b.fly()  ==  "I'm  a  flying  Colibri!"
    Traits: multiple inheritance (& dynamism)
    implements two traits!

    View Slide

  38. @glaforge
    #dvxgroovy
    trait  FlyingAbility  {  
           String  fly()  {  "I'm  a  flying  $name!"  }  
    }  
    !
    trait  Named  {  String  name  }  
    !
    class  Bird  implements  Named,  FlyingAbility  {}  
    def  b  =  new  Bird(name:  'Colibri')  
    !
    assert  b.name  ==  'Colibri'  
    assert  b.fly()  ==  "I'm  a  flying  Colibri!"
    Traits: multiple inheritance (& dynamism)
    dynamic ‘name’
    property interpolated

    View Slide

  39. @glaforge
    #dvxgroovy
    trait  FlyingAbility  {  
           String  fly()  {  "I'm  a  flying  $name!"  }  
    }  
    !
    trait  Named  {  String  name  }  
    !
    class  Bird  implements  Named,  FlyingAbility  {}  
    def  b  =  new  Bird(name:  'Colibri')  
    !
    assert  b.name  ==  'Colibri'  
    assert  b.fly()  ==  "I'm  a  flying  Colibri!"
    Traits: multiple inheritance (& dynamism)

    View Slide

  40. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  41. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    two surf() methods

    View Slide

  42. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  43. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    extending a class and
    implementing the two traits

    View Slide

  44. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  45. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    last declared trait wins!

    View Slide

  46. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  47. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  48. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    reverse the order!

    View Slide

  49. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  50. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  51. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    Be explicit!
    Override surf() 

    & use ‘super’

    View Slide

  52. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?
    Your class method takes
    precedence over the traits

    View Slide

  53. @glaforge
    #dvxgroovy
    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'
    Traits: what about conflicts?

    View Slide

  54. @glaforge
    #dvxgroovy
    !
    !
    trait  CustomToString  {  
    !
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  !=  'a  Foo  instance'
    Traits: forcing method override

    View Slide

  55. @glaforge
    #dvxgroovy
    !
    !
    trait  CustomToString  {  
    !
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  !=  'a  Foo  instance'
    Traits: forcing method override
    ‘this’ is the ‘this’ of the class
    implementing the trait

    View Slide

  56. @glaforge
    #dvxgroovy
    !
    !
    trait  CustomToString  {  
    !
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  !=  'a  Foo  instance'
    Traits: forcing method override
    The default Object#toString()
    method always prevails, 

    in spite of the trait’s toString()

    View Slide

  57. @glaforge
    #dvxgroovy
    !
    !
    trait  CustomToString  {  
    !
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  !=  'a  Foo  instance'
    Traits: forcing method override

    View Slide

  58. @glaforge
    #dvxgroovy
    import  groovy.transform.ForceOverride  
    !
    trait  CustomToString  {  
           @ForceOverride  
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  ==  'a  Foo  instance'
    Traits: forcing method override

    View Slide

  59. @glaforge
    #dvxgroovy
    import  groovy.transform.ForceOverride  
    !
    trait  CustomToString  {  
           @ForceOverride  
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  ==  'a  Foo  instance'
    Traits: forcing method override
    Use @ForceOverride to force the
    compiler to use the trait’s method

    View Slide

  60. @glaforge
    #dvxgroovy
    import  groovy.transform.ForceOverride  
    !
    trait  CustomToString  {  
           @ForceOverride  
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  ==  'a  Foo  instance'
    Traits: forcing method override
    If Foo had implemented toString(),
    Foo’s toString() would always win

    View Slide

  61. @glaforge
    #dvxgroovy
    import  groovy.transform.ForceOverride  
    !
    trait  CustomToString  {  
           @ForceOverride  
           String  toString()  {  
                   "a  ${this.class.name}  instance"  
           }  
    }  
    !
    class  Foo  implements  CustomToString  {}  
    !
    assert  new  Foo().toString()  ==  'a  Foo  instance'
    Traits: forcing method override

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  66. @glaforge
    #dvxgroovy
    trait  Named  {  
           String  name  
    }  
    !
    class  Animal  {}  
    !
    !
    def  na  =  new  Animal()  as  Named  
    na.name  =  'Felix'  
    assert  na.name  ==  'Felix'
    Traits: runtime implementation
    Runtime trait, 

    with Groovy’s usual
    coercion mechanism

    View Slide

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

    View Slide

  68. @glaforge
    #dvxgroovy
    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!'
    Traits: runtime implementation

    View Slide

  69. @glaforge
    #dvxgroovy
    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!'
    Traits: runtime implementation
    Implement several traits
    at once, at runtime

    View Slide

  70. @glaforge
    #dvxgroovy
    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!'
    Traits: runtime implementation

    View Slide

  71. @glaforge
    #dvxgroovy
    Traits: miscellaneous
    • Traits can…

    !
    • have private fields and methods

    • have abstract methods

    • implement interfaces

    • extend other traits or implement several traits

    • be statically type checked and compiled

    View Slide

  72. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    A
    ST
    transform
    s

    View Slide

  73. @glaforge
    #dvxgroovy
    New: @TailRecursive
    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

    View Slide

  74. @glaforge
    #dvxgroovy
    New: @TailRecursive
    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

    View Slide

  75. @glaforge
    #dvxgroovy
    New: @TailRecursive
    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

    View Slide

  76. @glaforge
    #dvxgroovy
    New: @TailRecursive
    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

    View Slide

  77. @glaforge
    #dvxgroovy
    New: @TailRecursive
    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

    View Slide

  78. @glaforge
    #dvxgroovy
    New: @Sortable
    import  groovy.transform.*  
    !
    @Sortable  
    class  Person  {  
           String  lastName  
           String  firstName  
           int  age  
    }

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  82. @glaforge
    #dvxgroovy
    New: @Sortable
    import  groovy.transform.*  
    !
    @Sortable  
    class  Person  {  
           String  lastName  
           String  firstName  
           int  age  
    }

    View Slide

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

    View Slide

  84. @glaforge
    #dvxgroovy
    @BaseScript improvements
    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

    View Slide

  85. @glaforge
    #dvxgroovy
    @BaseScript improvements
    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

    View Slide

  86. @glaforge
    #dvxgroovy
    @BaseScript improvements
    abstract  class  CustomBase  extends  Script  {  
           int  meaningOfLife  =  42  
    }
    @BaseScript(CustomBase)  
    import  groovy.transform.BaseScript  
    !
    assert  meaningOfLife  ==  42
    In 2.3, ability to put
    the annotation on
    imports & package

    View Slide

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

    View Slide

  88. @glaforge
    #dvxgroovy
    @BaseScript custom abstract method
    abstract  class  CustomBase  extends  Script  {  
           def  run()  {  
                   before()  
                   internalRun()  
                   after()  
           }  
    !
           abstract  internalRun()  
    !
           def  before()  {  println  'before'  }  
           def  after()    {  println  'after'    }  
    }

    View Slide

  89. @glaforge
    #dvxgroovy
    @BaseScript custom abstract method
    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'

    View Slide

  90. @glaforge
    #dvxgroovy
    @BaseScript custom abstract method
    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

    View Slide

  91. @glaforge
    #dvxgroovy
    @BaseScript custom abstract method
    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'

    View Slide

  92. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    N
    IO
    2
    m
    odule

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  96. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    JSO
    N

    View Slide

  97. @glaforge
    #dvxgroovy
    JSON parser / builder performance increase
    • Re-implementation of JSON support for speed & efficiency

    • parser forked of 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

    View Slide

  98. @glaforge
    #dvxgroovy
    JSON parser / builder performance increase
    • Re-implementation of JSON support for speed & efficiency

    • parser forked of 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

    View Slide

  99. @glaforge
    #dvxgroovy
    JSON parser / builder performance increase
    • Re-implementation of JSON support for speed & efficiency

    • parser forked of 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
    Benchmark gives 3x to 4x
    performance factor 

    over Jackson and GSON

    View Slide

  100. @glaforge
    #dvxgroovy
    JSON parser / builder performance increase
    • Re-implementation of JSON support for speed & efficiency

    • parser forked of 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

    View Slide

  101. @glaforge
    #dvxgroovy
    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

    View Slide

  102. @glaforge
    #dvxgroovy
    JsonSlurper for configuration files
    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

    View Slide

  103. @glaforge
    #dvxgroovy
    JsonSlurper for configuration files
    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

    View Slide

  104. @glaforge
    #dvxgroovy
    JsonSlurper for configuration files
    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

    View Slide

  105. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    M
    arkup
    tem
    plate
    engine

    View Slide

  106. @glaforge
    #dvxgroovy
    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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  110. @glaforge
    #dvxgroovy
    Markup template engine — the idea
    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

    View Slide

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

    View Slide

  112. @glaforge
    #dvxgroovy
    Markup template engine — the idea
    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

    View Slide

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

    View Slide

  114. @glaforge
    #dvxgroovy
    Markup template engine — in action
    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)

    View Slide

  115. @glaforge
    #dvxgroovy
    Markup template engine — includes
    //  include  another  template  
    include  template:  'foo.tpl'  
           
    //  include  raw  content  
    include  unescaped:  'raw.txt'  
    !
    //  escape  &  include  
    include  escaped:  'to_escape.txt'

    View Slide

  116. @glaforge
    #dvxgroovy
    Markup template engine — useful methods
    //  escaped  automatically  
    yield  'some  raw  content'  
    !
    //  include  raw  content  
    yieldUnescaped  'content'  
    !
    //    
    xmlDeclaration()                

    View Slide

  117. @glaforge
    #dvxgroovy
    Markup template engine — useful methods
    //  escaped  automatically  
    yield  'some  raw  content'  
    !
    //  include  raw  content  
    yieldUnescaped  'content'  
    !
    //    
    xmlDeclaration()                
    //    
    comment  'comment'                
    !
    //  adds  new  lines  
    newLine()                                
    !
    //  processing  instructions  
    pi(/*  ...  */)                      

    View Slide

  118. @glaforge
    #dvxgroovy
    Markup template engine — configuration
    • Configuration options

    !
    • declaration encoding

    !
    • expand empty elements

    !
    • use double quotes

    !
    • newline string

    !
    !
    !
    !
    • auto escape

    !
    • auto indent

    !
    • base template class

    !
    • locale

    View Slide

  119. @glaforge
    #dvxgroovy
    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

    View Slide

  120. @glaforge
    #dvxgroovy
    Markup template engine — static!
    • With typed check model
    creation method

    !
    !
    !
    !
    !
    • Alternative: 

    declare your model types
    in the template

    View Slide

  121. @glaforge
    #dvxgroovy
    Markup template engine — static!
    • With typed check model
    creation method

    !
    !
    !
    !
    !
    • Alternative: 

    declare your model types
    in the template
    def  modelTypes  =  [cars:  "List"]  
    !
    def  tmpl  =  engine.  
       createTypeCheckedModelTemplate(

               "page.tpl",  modelTypes)

    View Slide

  122. @glaforge
    #dvxgroovy
    Markup template engine — static!
    • With typed check model
    creation method

    !
    !
    !
    !
    !
    • Alternative: 

    declare your model types
    in the template
    def  modelTypes  =  [cars:  "List"]  
    !
    def  tmpl  =  engine.  
       createTypeCheckedModelTemplate(

               "page.tpl",  modelTypes)
    modelTypes  =  {  
           List  cars  
    }  
    !
    cars.each  {  car  -­‐>  
           p("Car  name:  $car.name")  
    }

    View Slide

  123. @glaforge
    #dvxgroovy
    Markup template engine — static!
    • With typed check model
    creation method

    !
    !
    !
    !
    !
    • Alternative: 

    declare your model types
    in the template
    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

    View Slide

  124. @glaforge
    #dvxgroovy
    Markup template engine — static!
    • With typed check model
    creation method

    !
    !
    !
    !
    !
    • Alternative: 

    declare your model types
    in the template
    def  modelTypes  =  [cars:  "List"]  
    !
    def  tmpl  =  engine.  
       createTypeCheckedModelTemplate(

               "page.tpl",  modelTypes)
    modelTypes  =  {  
           List  cars  
    }  
    !
    cars.each  {  car  -­‐>  
           p("Car  name:  $car.name")  
    }

    View Slide

  125. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    D
    ocum
    entation
    overhaul

    View Slide

  126. @glaforge
    #dvxgroovy
    GroovyDoc: new style

    View Slide

  127. @glaforge
    #dvxgroovy
    GroovyDoc: new style

    View Slide

  128. @glaforge
    #dvxgroovy
    GroovyDoc: new style

    View Slide

  129. @glaforge
    #dvxgroovy
    Groovy GDK documentation: new style

    View Slide

  130. @glaforge
    #dvxgroovy
    Groovy GDK documentation: new style

    View Slide

  131. @glaforge
    #dvxgroovy
    Brand new documentation with Asciidoctor

    View Slide

  132. @glaforge
    #dvxgroovy
    Future groovy-lang.org website

    View Slide

  133. @glaforge
    #dvxgroovy
    Future groovy-lang.org website

    View Slide

  134. @glaforge
    #dvxgroovy
    Future groovy-lang.org website

    View Slide

  135. @YourTwitterHandle
    #DVXFR14{session hashtag} @glaforge
    #dvxgroovy
    G
    roovy
    3.0

    View Slide

  136. View Slide

  137. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    M
    O
    P
    2

    View Slide

  138. @glaforge
    #dvxgroovy
    Goals for the new Meta-Object Protocol
    • Fully leverage and 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?

    View Slide

  139. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    A
    ntlr v4
    G
    ram
    m
    ar

    View Slide

  140. @glaforge
    #dvxgroovy
    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!

    View Slide

  141. @glaforge
    #dvxgroovy
    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!
    A « Groovy Summer of
    Code » student to help

    View Slide

  142. @YourTwitterHandle
    @glaforge
    #dvxgroovy
    Java
    8
    support

    View Slide

  143. @glaforge
    #dvxgroovy
    Java 8 support
    • Additional grammar and 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

    View Slide

  144. @glaforge
    #dvxgroovy
    Java 8 support
    • Additional grammar and 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
    Groovy had already:
    closures, method pointers, mixins,
    enriched collection & time APIs

    View Slide

  145. @YourTwitterHandle
    #DVXFR14{session hashtag} @glaforge
    #dvxgroovy
    Sum
    m
    ary

    View Slide

  146. View Slide

  147. Groovy rocks the JVM 

    since 2003!

    View Slide

  148. @YourTwitterHandle
    #DVXFR14{session hashtag} @glaforge
    #dvxgroovy
    Q
    &
    A

    View Slide

  149. @glaforge
    #dvxgroovy
    Crédit image / Creative Commons
    • Rue pavée — By-Nc-Sa

    • http://www.flickr.com/photos/22914687@N05/4957591422/sizes/l/

    • Sous la Tour Eiffel — By-Nc-Sa

    • http://www.flickr.com/photos/stewiedewie/244850735/sizes/l/in/photostream/

    • Sous le pont — By-Nc-Nd

    • http://www.landscape-photo.net/displayimage.php?pid=5194

    • Paris Metro - By-Nc-Sa

    • http://www.flickr.com/photos/22914687@N05/6317047263/sizes/l/

    !
    • Slide template created by @glaforge, completed by @nmartignole for Devoxx FR2014

    View Slide