groovy in 2014 and beyond

160
© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission. Groovy, in 2014 and beyond Guillaume Laforge — Groovy project lead / Pivotal @glaforge

Upload: spring-io

Post on 02-Jul-2015

801 views

Category:

Software


2 download

DESCRIPTION

With 3 million downloads in a year, Groovy still clearly leads the pack of alternative languages on the JVM, but it's not resting on its laurels. The latest Groovy 2.3 release is pack full of useful new features and performance improvements. In particular, Groovy now supports the concept of "traits" for elegantly composing behaviors. Its JSON support is now the most performant among all the JSON libraries available to date. Groovy 2.3 introduces a new markup-based template engine, new code transformations, and much more.

TRANSCRIPT

Page 1: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Groovy, in 2014 and beyondGuillaume Laforge — Groovy project lead / Pivotal

@glaforge

Page 2: Groovy in 2014 and Beyond

Stay up-to-date

Groovy Weekly Newsletter (Every Tuesday) http://beta.groovy-lang.org/groovy-weekly.html

2

Page 3: Groovy in 2014 and Beyond

Stay up-to-date

Google+ Groovy Page https://google.com/+groovy

3

Page 4: Groovy in 2014 and Beyond

Stay up-to-date

Google+ Groovy Community http://bit.ly/g-community

4

Page 5: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Agenda

Page 6: Groovy in 2014 and Beyond

The Groovy roadmap

6

2015 20142013

Groovy 2.3

Groovy 2.4Groovy 2.2

Groovy 2.5 ?

Groovy 3.0 ?

Page 7: Groovy in 2014 and Beyond

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

7

Page 8: Groovy in 2014 and Beyond

Groovy 2.4

• Android support !

• New website !

• Potentially • Macro system? • New grammar?

8

Page 9: Groovy in 2014 and Beyond

Groovy 3.0

• New Meta-Object Protocol !

• Invoke-dynamic based runtime !

• Rewritten language grammar with Antlr v4 • unless re-scheduled for Groovy 2.4 • successful GSoC, but not fully complete coverage

9

Page 10: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Groovy 2.3

Page 11: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

JDK 8 support

Page 12: Groovy in 2014 and Beyond

JDK 8 support — closures vs lambdas

12

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));

Page 13: Groovy in 2014 and Beyond

JDK 8 support — closures vs lambdas

12

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  }

Page 14: Groovy in 2014 and Beyond

JDK 8 support — closures vs lambdas

12

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 closureswherever you passlambdas in Java 8

Page 15: Groovy in 2014 and Beyond

To know all about AST transformations!

13

Groovy in the light of Java 8 by Guillaume Laforge Tue 12:45pm / F. Park 1

Page 16: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Traits

Page 17: Groovy in 2014 and Beyond

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 15

Page 18: Groovy in 2014 and Beyond

Traits: a simple example

16

trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }  }  !

class  Bird  implements  FlyingAbility  {}  def  b  =  new  Bird()  !

assert  b.fly()  ==  "I'm  flying!"

Page 19: Groovy in 2014 and Beyond

Traits: a simple example

16

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

Page 20: Groovy in 2014 and Beyond

Traits: a simple example

16

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

Page 21: Groovy in 2014 and Beyond

Traits: a simple example

16

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

Page 22: Groovy in 2014 and Beyond

Traits: a simple example

16

trait  FlyingAbility  {          String  fly()  {  "I'm  flying!"  }  }  !

class  Bird  implements  FlyingAbility  {}  def  b  =  new  Bird()  !

assert  b.fly()  ==  "I'm  flying!"

Page 23: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

Page 24: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

a Groovy property

Page 25: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

implement the trait

Page 26: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

Groovy named argument constructor

Page 27: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

access the property

Page 28: Groovy in 2014 and Beyond

Traits: stateful

17

trait  Named  {          String  name  }  !

class  Bird  implements  Named  {}  def  b  =  new  Bird(name:  'Colibri')  !

assert  b.name  ==  'Colibri'

Page 29: Groovy in 2014 and Beyond

Traits: inheritance

18

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!"

Page 30: Groovy in 2014 and Beyond

Traits: inheritance

18

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

Page 31: Groovy in 2014 and Beyond

Traits: inheritance

18

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

Page 32: Groovy in 2014 and Beyond

Traits: inheritance

18

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

Page 33: Groovy in 2014 and Beyond

Traits: inheritance

18

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!"

Page 34: Groovy in 2014 and Beyond

Traits: multiple inheritance & dynamic access

19

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!"

Page 35: Groovy in 2014 and Beyond

Traits: multiple inheritance & dynamic access

19

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!"

access a dynamic property

Page 36: Groovy in 2014 and Beyond

Traits: multiple inheritance & dynamic access

19

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!"

implements two traits!

Page 37: Groovy in 2014 and Beyond

Traits: multiple inheritance & dynamic access

19

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!"

dynamic ‘name’ property interpolated

Page 38: Groovy in 2014 and Beyond

Traits: multiple inheritance & dynamic access

19

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!"

Page 39: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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'

Page 40: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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

Page 41: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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'

Page 42: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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

Page 43: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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'

Page 44: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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!

Page 45: Groovy in 2014 and Beyond

Traits: what about conflicts?

20

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'

Page 46: Groovy in 2014 and Beyond

Traits: what about conflicts?

21

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'

Page 47: Groovy in 2014 and Beyond

Traits: what about conflicts?

21

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!

Page 48: Groovy in 2014 and Beyond

Traits: what about conflicts?

21

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'

Page 49: Groovy in 2014 and Beyond

Traits: what about conflicts?

22

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'

Page 50: Groovy in 2014 and Beyond

Traits: what about conflicts?

22

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’

Page 51: Groovy in 2014 and Beyond

Traits: what about conflicts?

22

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

Page 52: Groovy in 2014 and Beyond

Traits: what about conflicts?

22

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'

Page 53: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  class  NamedAnimal  implements  Named  {}  !

def  na  =  new  NamedAnimal(name:  'Felix')  !

assert  na.name  ==  'Felix'

Traits: runtime implementation

23

Page 54: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  class  NamedAnimal  implements  Named  {}  !

def  na  =  new  NamedAnimal(name:  'Felix')  !

assert  na.name  ==  'Felix'

Traits: runtime implementation

23

Somewhat artificial to have to create an intermediary class to

get named animals

Page 55: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  class  NamedAnimal  implements  Named  {}  !

def  na  =  new  NamedAnimal(name:  'Felix')  !

assert  na.name  ==  'Felix'

Traits: runtime implementation

23

Page 56: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  !

!

def  na  =  new  Animal()  as  Named  na.name  =  'Felix'  assert  na.name  ==  'Felix'

Traits: runtime implementation

24

Page 57: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  !

!

def  na  =  new  Animal()  as  Named  na.name  =  'Felix'  assert  na.name  ==  'Felix'

Traits: runtime implementation

24

Runtime trait, with Groovy’s usual

coercion mechanism

Page 58: Groovy in 2014 and Beyond

trait  Named  {          String  name  }  !

class  Animal  {}  !

!

def  na  =  new  Animal()  as  Named  na.name  =  'Felix'  assert  na.name  ==  'Felix'

Traits: runtime implementation

24

Page 59: Groovy in 2014 and Beyond

Traits: runtime implementation

25

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!'

Page 60: Groovy in 2014 and Beyond

Traits: runtime implementation

25

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

Page 61: Groovy in 2014 and Beyond

Traits: runtime implementation

25

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!'

Page 62: Groovy in 2014 and Beyond

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

26

Page 63: Groovy in 2014 and Beyond

To know all about traits!

27

Rethinking API design with traits by Cédric Champeau Tue 2:30pm / Trinity 3

Page 64: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

AST transforms

Page 65: Groovy in 2014 and Beyond

New: @TailRecursive

29

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

Page 66: Groovy in 2014 and Beyond

New: @TailRecursive

29

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

Page 67: Groovy in 2014 and Beyond

New: @TailRecursive

29

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

Page 68: Groovy in 2014 and Beyond

New: @TailRecursive

29

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

Page 69: Groovy in 2014 and Beyond

New: @TailRecursive

29

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

Page 70: Groovy in 2014 and Beyond

New: @Sortable

30

import  groovy.transform.*  !

@Sortable  class  Person  {          String  lastName          String  firstName          int  age  }

Page 71: Groovy in 2014 and Beyond

New: @Sortable

30

import  groovy.transform.*  !

@Sortable  class  Person  {          String  lastName          String  firstName          int  age  }

Makes the class Comparable by multiple Comparators

Page 72: Groovy in 2014 and Beyond

New: @Sortable

30

import  groovy.transform.*  !

@Sortable  class  Person  {          String  lastName          String  firstName          int  age  }

First compare by lastName, then by firstName, etc.

Page 73: Groovy in 2014 and Beyond

New: @Sortable

30

import  groovy.transform.*  !

@Sortable  class  Person  {          String  lastName          String  firstName          int  age  }

You can also specify ‘includes’ / ‘excludes’

properties

Page 74: Groovy in 2014 and Beyond

New: @Sortable

30

import  groovy.transform.*  !

@Sortable  class  Person  {          String  lastName          String  firstName          int  age  }

Page 75: Groovy in 2014 and Beyond

@BaseScript improvements

31

abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42  }

@BaseScript(CustomBase)  import  groovy.transform.BaseScript  !

assert  meaningOfLife  ==  42

Page 76: Groovy in 2014 and Beyond

@BaseScript improvements

31

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

Page 77: Groovy in 2014 and Beyond

@BaseScript improvements

31

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

Page 78: Groovy in 2014 and Beyond

@BaseScript improvements

31

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

Page 79: Groovy in 2014 and Beyond

@BaseScript improvements

31

abstract  class  CustomBase  extends  Script  {          int  meaningOfLife  =  42  }

@BaseScript(CustomBase)  import  groovy.transform.BaseScript  !

assert  meaningOfLife  ==  42

Page 80: Groovy in 2014 and Beyond

@BaseScript custom abstract method

32

abstract  class  CustomBase  extends  Script  {      def  run()  {          before()          internalRun()          after()      }  !    abstract  internalRun()  !    def  before()  {  println  'before'  }      def  after()    {  println  'after'    }  }

Page 81: Groovy in 2014 and Beyond

@BaseScript custom abstract method

32

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'

Page 82: Groovy in 2014 and Beyond

@BaseScript custom abstract method

32

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

Page 83: Groovy in 2014 and Beyond

@BaseScript custom abstract method

32

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'

Page 84: Groovy in 2014 and Beyond

To know all about AST transformations!

33

Groovy AST transformations by Paul King Wed 2:30pm / Trinity 3

Page 85: Groovy in 2014 and Beyond

To know all about AST transformations!

34

Writing AST transformations by Simon / Sadogursky Thu 10:30pm / F. Park 3

Page 86: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

NIO2 module

Page 87: Groovy in 2014 and Beyond

JDK 7+ NIO2 module

• All the familiar methods on File retrofitted on Path as well

36

path.withReader  {  Reader  r  -­‐>  ...  }  path.eachLine  {  String  line  -­‐>  ...  }  path.eachFileRecurse  {  Path  p  -­‐>  ...  }  path  <<  'some  content'  path  <<  bytes  path.readLines()  …

Page 88: Groovy in 2014 and Beyond

JDK 7+ NIO2 module

• All the familiar methods on File retrofitted on Path as well

36

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

Page 89: Groovy in 2014 and Beyond

JDK 7+ NIO2 module

• All the familiar methods on File retrofitted on Path as well

36

path.withReader  {  Reader  r  -­‐>  ...  }  path.eachLine  {  String  line  -­‐>  ...  }  path.eachFileRecurse  {  Path  p  -­‐>  ...  }  path  <<  'some  content'  path  <<  bytes  path.readLines()  …

Page 90: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

JSON

Page 91: Groovy in 2014 and Beyond

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

38

Page 92: Groovy in 2014 and Beyond

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

38

Page 93: Groovy in 2014 and Beyond

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

38

Benchmark gives 3x to 4x performance factor

over Jackson and GSON

Page 94: Groovy in 2014 and Beyond

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

38

Page 95: Groovy in 2014 and Beyond

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

39

Page 96: Groovy in 2014 and Beyond

JsonSlurper for configuration files

40

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

Page 97: Groovy in 2014 and Beyond

JsonSlurper for configuration files

40

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

Page 98: Groovy in 2014 and Beyond

JsonSlurper for configuration files

40

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

Page 99: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Markup template engine

</>

Page 100: Groovy in 2014 and Beyond

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 42

Page 101: Groovy in 2014 and Beyond

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 42

Spring Boot approved

Page 102: Groovy in 2014 and Beyond

Markup template engine — the idea

43

cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }  }

Page 103: Groovy in 2014 and Beyond

Markup template engine — the idea

43

cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }  }

Your template

Page 104: Groovy in 2014 and Beyond

Markup template engine — the idea

43

cars  {        cars.each  {                car(make:  it.make,  name:  it.name)        }  }

model = [cars: [! new Car(make: 'Peugeot', name: '508'), ! new Car(make: 'Toyota', name: 'Prius’)!]]

Page 105: Groovy in 2014 and Beyond

Markup template engine — the idea

43

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

Page 106: Groovy in 2014 and Beyond

Markup template engine — the idea

43

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>

Page 107: Groovy in 2014 and Beyond

Markup template engine — the idea

43

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

Page 108: Groovy in 2014 and Beyond

Markup template engine — the idea

43

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>

Page 109: Groovy in 2014 and Beyond

Markup template engine — in action

44

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)

Page 110: Groovy in 2014 and Beyond

Markup template engine — includes

45

//  include  another  template  include  template:  'foo.tpl'          //  include  raw  content  include  unescaped:  'raw.txt'  !

//  escape  &  include  include  escaped:  'to_escape.txt'

Page 111: Groovy in 2014 and Beyond

Markup template engine

46

//  escaped  automatically  yield  'some  raw  content'  !//  include  raw  content  yieldUnescaped  'content'  !//  <?xml  version='1.0'?>  xmlDeclaration()                

Page 112: Groovy in 2014 and Beyond

Markup template engine

46

//  escaped  automatically  yield  'some  raw  content'  !//  include  raw  content  yieldUnescaped  'content'  !//  <?xml  version='1.0'?>  xmlDeclaration()                

//  <!-­‐-­‐comment-­‐-­‐>  comment  'comment'                !//  adds  new  lines  newLine()                                !//  process.  instruct.  pi(/*  ...  */)                      

Page 113: Groovy in 2014 and Beyond

Markup template engine — configuration options

!!!

• declaration encoding !

• expand empty elements !

• use double quotes !

• newline string !!!!!!!

!!

!• auto escape

!• auto indent

!• base template class

!• locale

47

Page 114: Groovy in 2014 and Beyond

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

48

Page 115: Groovy in 2014 and Beyond

Markup template engine — static!

• With typed check model creation method

!

!

!

!

!

!

!

!

!

• Or declare your model types in the template

49

Page 116: Groovy in 2014 and Beyond

Markup template engine — static!

• With typed check model creation method

!

!

!

!

!

!

!

!

!

• Or declare your model types in the template

49

def  modelTypes  =  [cars:  "List<Car>"]  !def  tmpl  =  engine.      createTypeCheckedModelTemplate(            "page.tpl",  modelTypes)

Page 117: Groovy in 2014 and Beyond

Markup template engine — static!

• With typed check model creation method

!

!

!

!

!

!

!

!

!

• Or declare your model types in the template

49

def  modelTypes  =  [cars:  "List<Car>"]  !def  tmpl  =  engine.      createTypeCheckedModelTemplate(            "page.tpl",  modelTypes)

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

Page 118: Groovy in 2014 and Beyond

Markup template engine — static!

• With typed check model creation method

!

!

!

!

!

!

!

!

!

• Or declare your model types in the template

49

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

Page 119: Groovy in 2014 and Beyond

Markup template engine — static!

• With typed check model creation method

!

!

!

!

!

!

!

!

!

• Or declare your model types in the template

49

def  modelTypes  =  [cars:  "List<Car>"]  !def  tmpl  =  engine.      createTypeCheckedModelTemplate(            "page.tpl",  modelTypes)

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

Page 120: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Documentation overhaul

Page 121: Groovy in 2014 and Beyond

GroovyDoc

51

Page 122: Groovy in 2014 and Beyond

GroovyDoc

51

Page 123: Groovy in 2014 and Beyond

GroovyDoc

51

Page 124: Groovy in 2014 and Beyond

Groovy GDK documentation

52

Page 125: Groovy in 2014 and Beyond

Groovy GDK documentation

52

Page 126: Groovy in 2014 and Beyond

Brand new documentation

53

Page 127: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Groovy 2.4

Page 128: Groovy in 2014 and Beyond

Beta groovy-lang.org website

55

Page 129: Groovy in 2014 and Beyond

Beta groovy-lang.org website

55

Page 130: Groovy in 2014 and Beyond

Beta groovy-lang.org website

55

Page 131: Groovy in 2014 and Beyond

Beta groovy-lang.org website

55

Notice the « improve this doc » button!

Page 132: Groovy in 2014 and Beyond

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

56

Page 133: Groovy in 2014 and Beyond

New York Times — Getting Groovy with Android

57

Page 134: Groovy in 2014 and Beyond

New York Times — Getting Groovy with Android

57

http://bit.ly/nyt-groovy

Page 135: Groovy in 2014 and Beyond

Android support

58

Page 136: Groovy in 2014 and Beyond

Android support

58

Page 137: Groovy in 2014 and Beyond

Android support

58

Source code available:https://github.com/melix/gr8confagenda

Page 138: Groovy in 2014 and Beyond

To know all about AST transformations!

59

Groovy & Android, a winning pair? by Cédric Champeau Thu 12:45pm / Trinity 3

Page 139: Groovy in 2014 and Beyond

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

60

Page 140: Groovy in 2014 and Beyond

Groovy Macros

!

• Authoring AST transformations can be verbose:

61

def  someVariable  =  new  ConstantExpression("xyz")  def  returnStatement  =  new  ReturnStatement(          new  ConstructorCallExpression(                  ClassHelper.make(SomeCoolClass),                  new  ArgumentListExpression(someVariable)          )  )

Page 141: Groovy in 2014 and Beyond

Groovy Macros

• With Groovy Macros, it could be simpler:

62

def  someVariable  =  macro  {  "xyz"  }  def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })    }

Page 142: Groovy in 2014 and Beyond

Groovy Macros

• With Groovy Macros, it could be simpler:

62

def  someVariable  =  macro  {  "xyz"  }  def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })    }

Special « macro » command

Page 143: Groovy in 2014 and Beyond

Groovy Macros

• With Groovy Macros, it could be simpler:

62

def  someVariable  =  macro  {  "xyz"  }  def  returnStatement  =  macro  {            new  SomeCoolClass($v{  someVariable  })    }

Special « macro » command

Quasi-quotation

Page 144: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Groovy 3.0

Page 145: Groovy in 2014 and Beyond
Page 146: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

New Age Meta-Object Protocol

MOP 2

Page 147: Groovy in 2014 and Beyond

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?

66

Page 148: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Rewriting the Groovy grammar

with Antlr v4

Antlr v4 Grammar

Page 149: Groovy in 2014 and Beyond

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!

68

Page 150: Groovy in 2014 and Beyond

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!

68

A « Google Summer of Code » student is currently helping

Page 151: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Support the new Java 8

language features

Java 8 language support

Page 152: Groovy in 2014 and Beyond

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

70

Page 153: Groovy in 2014 and Beyond

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

70

Groovy had already: closures, method pointers, mixins,

enriched collection & time APIs

Page 154: Groovy in 2014 and Beyond

To know all about AST transformations!

71

How to get Groovy with Java 8 by Peter Ledbrook Thu 10:30pm / Trinity 3

Page 155: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Summary

Page 156: Groovy in 2014 and Beyond
Page 157: Groovy in 2014 and Beyond

Groovy rocks the JVM since 2003!

Page 158: Groovy in 2014 and Beyond

© 2014 SpringOne 2GX. All rights reserved. Do not distribute without permission.

Q & A

Page 159: Groovy in 2014 and Beyond
Page 160: Groovy in 2014 and Beyond

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

76