what makes groovy groovy codeurs en seine - 2013 - light size

210
© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission. Guillaume Laforge @glaforge What makes Groovy groovy?

Upload: normandy-jug

Post on 06-May-2015

299 views

Category:

Technology


0 download

DESCRIPTION

Groovy n'est pas un nouveau venu dans l'arène des langages alternatifs pour la JVM, mais avec plus d'1.7 millions de téléchargements par an, c'est clairement le plus utilisé aujourd'hui ! Mais pourquoi choisir Groovy pour vos projets ? Que peut-il vous apporter ? - une courbe d'apprentissage minime - son intégration transparente avec Java pour mixer Groovy et Java ensemble - une syntax malléable, concise et lisible adaptée aux Domain-Specific Languages - une approche pragmatique sur le typage - un riche écosystème de projets, comme Grails, Gradle, GPars, Spock, Geb, etc... Dans cette session, vous découvrirez comment tout s'articule dans l'univers Groovy, ainsi que où, quand, comment vous pourrez tirer avantage de Groovy pour améliorer votre productivité.

TRANSCRIPT

Page 1: What makes groovy groovy   codeurs en seine - 2013 - light size

© 2013 Guillaume Laforge. All rights reserved. Do not distribute without permission.

Guillaume Laforge @glaforge !

What makes Groovy groovy?

Page 2: What makes groovy groovy   codeurs en seine - 2013 - light size

Guillaume Laforge

Groovy project leadat .

@glaforgehttp://glaforge.appspot.com

Page 3: What makes groovy groovy   codeurs en seine - 2013 - light size

Les Cast Codeurs

Page 4: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 5: What makes groovy groovy   codeurs en seine - 2013 - light size

The Groovy vision

Part 1

Page 6: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 7: What makes groovy groovy   codeurs en seine - 2013 - light size

Simplify the life of (Java) developers

Page 8: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 9: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 10: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 11: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 12: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 13: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 14: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 15: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 16: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Page 17: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Fit for Domain-Specific Languages

Page 18: What makes groovy groovy   codeurs en seine - 2013 - light size

Great for scripting

Fit for Domain-Specific Languages

Most seamless integration & interoperability wih java!

Page 19: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 20: What makes groovy groovy   codeurs en seine - 2013 - light size

It’s so easy to learn!

Page 21: What makes groovy groovy   codeurs en seine - 2013 - light size

It’s so easy to learn!

Groovy as a Java superset

Page 22: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 23: What makes groovy groovy   codeurs en seine - 2013 - light size

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

Page 24: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 25: What makes groovy groovy   codeurs en seine - 2013 - light size

As safe and fast as Java with static type checking & compilation

Page 26: What makes groovy groovy   codeurs en seine - 2013 - light size

As safe and fast as Java with static type checking & compilation

Page 27: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 28: What makes groovy groovy   codeurs en seine - 2013 - light size

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}

!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!rocks!"!!!!!!!!}!!!!}}

Page 29: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 30: What makes groovy groovy   codeurs en seine - 2013 - light size

move!forward!at!3.km/h

Expressive, Concise, Readable

Page 31: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 32: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 33: What makes groovy groovy   codeurs en seine - 2013 - light size

@RestControllerclass!App!{!!!!@RequestMapping("/")!!!!String!home()!{!"Hello!World!"!}}

Speaking of conciseness...A full Spring app in the span of a tweet!

Page 34: What makes groovy groovy   codeurs en seine - 2013 - light size

Serv

ices

Tech

nolo

gy

IoT

Fina

ncia

l

Inte

rnet

Who’s using Groovy?

• Netflix• LinkedIn• Google

• Crédit Suisse• JPMorgan• Fanny Mae• Mutual of Omaha• Hypoport

• Energy Transfer• National Cancer Inst.• IRSN

• European Patent Office

• Amadeus

• SmartThings• Carriots

20

Page 35: What makes groovy groovy   codeurs en seine - 2013 - light size

Cool Groovy gems

Part 2

Page 36: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 37: What makes groovy groovy   codeurs en seine - 2013 - light size

Most Java code is also valid Groovy code!

Page 38: What makes groovy groovy   codeurs en seine - 2013 - light size

Any Java developer is a Groovy developer!

Most Java code is also valid Groovy code!

Page 39: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 40: What makes groovy groovy   codeurs en seine - 2013 - light size

Flat learning curve

Page 41: What makes groovy groovy   codeurs en seine - 2013 - light size

Flat learning curve

Easy to learn

Page 42: What makes groovy groovy   codeurs en seine - 2013 - light size

Scripts versus Classes

24

public!class!Main!{!!!!public!static!void!main(String[]!args)!{!!!!!!!!System.out.println("Hello");!!!!}}

vs

Page 43: What makes groovy groovy   codeurs en seine - 2013 - light size

Scripts versus Classes

24

public!class!Main!{!!!!public!static!void!main(String[]!args)!{!!!!!!!!System.out.println("Hello");!!!!}}

println!"Hello"

vs

Page 44: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

Page 45: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

Semicolons

Page 46: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

Page 47: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword

Page 48: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword public keyword

Page 49: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional

SemicolonsParentheses

return keyword public keyword

Typing!

Page 50: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

26

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Page 51: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

26

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Semicolons

Page 52: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

27

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Page 53: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

28

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Page 54: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

28

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner("Guillaume")

System.out.println(greeter.greet("Marion"))

Parentheses

Page 55: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

29

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 56: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

29

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!return!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

return keyword

Page 57: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

30

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 58: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

30

public!class!Greeter!{!!!!private!String!owner

!!!!public!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

public keyword

Page 59: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

31

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 60: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

31

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

Greeter!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

optional typing

Page 61: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

32

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

Page 62: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

32

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

System.out.println!greeter.greet("Marion")

handy println shortcut

Page 63: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

33

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 64: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

33

******!class!Greeter!{!!!!private!String!owner

!!!!******!String!getOwner()!{!!!!!!!!******!owner!!!!}

!!!!******!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner!!!!}

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

verbose Java properties!

Page 65: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

34

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 66: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

34

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.setOwner!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Property notation

Page 67: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

35

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.owner!!!!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Page 68: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

35

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter()greeter.owner!!!!"Guillaume"

!!!!!!!!!!!println!greeter.greet("Marion")

Named argument constructor

Page 69: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

36

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Page 70: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

36

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!"!+!name!+!",!I!am!"!+!owner!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Interpolated strings!(aka GStrings)

Page 71: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

37

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!${name},!I!am!${owner}"!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Page 72: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

37

******!class!Greeter!{!!!!*******!String!owner

!!!!*******String!greet(String!name)!{!!!!!!!!******!"Hello!${name},!I!am!${owner}"!!!!}}

def!!!!!greeter!=!new!Greeter(owner:!"Guillaume")

!!!!!!!!!!!println!greeter.greet("Marion")

Let’s reformat that mess of whitespace!

Page 73: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

Page 74: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

public!class!Greeter!{!!!!private!String!owner;

!!!!public!String!getOwner()!{!!!!!!!!return!owner;!!!!}

!!!!public!void!setOwner(String!owner)!{!!!!!!!!this.owner!=!owner;!!!!}

!!!!public*String!greet(String!name)!{!!!!!!!!return!"Hello!"!+!name!+!",!I!am!"!+!owner;!!!!}}

Greeter!greeter!=!new!Greeter();greeter.setOwner("Guillaume");

System.out.println(greeter.greet("Marion"));

Page 75: What makes groovy groovy   codeurs en seine - 2013 - light size

Optional...

38

class!Greeter!{***!String!owner

****String!greet(String!name)!{******!"Hello!${name},!I!am!${owner}"!!!!}}

def!greeter!=!new!Greeter(owner:!"Guillaume")

println!greeter.greet("Marion")

Page 76: What makes groovy groovy   codeurs en seine - 2013 - light size

Native syntax constructs

• Closures

• Lists

• Maps

• Regular expressions

• Ranges

39

Page 77: What makes groovy groovy   codeurs en seine - 2013 - light size

Closures

• Functions as first-class citizen of the language

40

Page 78: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

Page 79: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definition

Page 80: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definitionAppend an element

(operator overloading)

Page 81: What makes groovy groovy   codeurs en seine - 2013 - light size

Lists

41

def!list!=!['a',!'b',!'c']

list!<<!'d'assert!list.contains('d')

assert!list.findAll!{!it.startsWith!'a'!}.size()!==!1assert!list.collect!{!it.toUpperCase()!}!==!['A',!'B',!'C',!'D']assert!list.inject('')!{!a,!b!c>!a!+!b!}!==!'abcd'

List definitionAppend an element

(operator overloading)

Functional-style map / filter / reduce

with closures

Page 82: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Page 83: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Page 84: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Indexed access

Page 85: What makes groovy groovy   codeurs en seine - 2013 - light size

Maps

42

def!map!=![name:!'Guillaume',!age:!36]

map.daughters!=!['Marion',!'Erine']

assert!map['daughters'].contains('Marion')

Map definition

Indexed accessProperty notation access

Page 86: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

Page 87: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

Pattern

Page 88: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Page 89: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Find

Page 90: What makes groovy groovy   codeurs en seine - 2013 - light size

Regular expressions

43

def!pattern!=!~/.*foo.*/

assert!"Alibaba"!==~!/.*(ba){2}/

def!matcher!=!"Superman"!=~!/([AcZ][acz]+)man/assert!matcher[0][0]!==!'Superman'assert!matcher[0][1]!==!'Super'

'75001!Paris'.find(/(\d{5})\s(\w)+/)!{!match,!cp,!town!c>!!!!println!"The!Zip!code!of!${town}!is!${cp}"}

PatternMatch

Find

Nice way to decompose the matched regions

Page 91: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Page 92: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Page 93: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Page 94: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Reverse range

Page 95: What makes groovy groovy   codeurs en seine - 2013 - light size

Ranges

44

def!range!=!'a'..'z'

assert!range.contains('m')assert!range.contains('z')

def!exclusive!=!1..<10

assert!!exclusive.contains(10)

def!reverse!=!10..0

assert!reverse[0]!==!10assert!reverse[c1]!==!0

Range

Excluded upper bound

Reverse range

Negative index count from the end

Page 96: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Page 97: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Plain java.lang.String

Page 98: What makes groovy groovy   codeurs en seine - 2013 - light size

Strings, GStrings, multiline strings

45

def!name!=!'Groovy'def!tmpl!=!"""!!!!Dear!Mr!${name},!!!!You're!the!winner!of!the!lottery!!!!!Yours!sincerly,!!!!Dave"""

assert!tmpl.toString().contains('Groovy')

Plain java.lang.String

Multiline string with expression interpolation

Page 99: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

Page 100: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

0.8999999999999999

Page 101: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

46

System.out.println(!2.0!c!1.1!);

0.8999999999999999

Page 102: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

Page 103: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

1

Page 104: What makes groovy groovy   codeurs en seine - 2013 - light size

Surprising numbers...

47

System.out.println(!3!/!2!);

1

Page 105: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

Page 106: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

One of the reasons why micro-benchmarks sometimes showed

Groovy to be slow...

Page 107: What makes groovy groovy   codeurs en seine - 2013 - light size

BigDecimal by default!

48

assert!2.0!c!1.1!==!0.9

assert!3!/!2!==!1.5

One of the reasons why micro-benchmarks sometimes showed

Groovy to be slow...

But you can use doubles & floats for performance, with ‘d’ or ‘f ’ suffixes or with explicit type

Page 108: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 109: What makes groovy groovy   codeurs en seine - 2013 - light size

Powerful switch / case

on steroids

Page 110: What makes groovy groovy   codeurs en seine - 2013 - light size

Powerful switch / case

on steroids

switch(obj)!{!!!!case!123:!!!!!!!!!!!!!!!!!!"number!123";!!!!!!!!break!!!!case!"abc":!!!!!!!!!!!!!!!!"string!abc";!!!!!!!!break!!!!case!String:!!!!!!!!!!!!!!!"is!a!string";!!!!!!!break!!!!case![1,!2,!3]:!!!!!!!!!!!!"contained!in!list";!break!!!!case!~/.*o+.*/:!!!!!!!!!!!!"match!the!regex";!!!break!!!!case!{!it.isUpperCase()!}:!"closure!criteria";!!break****default:!"unknown"}

Page 111: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Page 112: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument

Page 113: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument Named argument

Page 114: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments

50

move!obj,!x:!3,!y:!4

Normal argument Named argument

Calls:move(Map m, Object)

Page 115: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

Page 116: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

move!forward!at!3.km/h

Page 117: What makes groovy groovy   codeurs en seine - 2013 - light size

Command chains

• Ability to chain method calls without parentheses and dots

51

move!forward!at!3.km/h

Actually equivalent to:move(forward).at(3.getKm().div(h))

Page 118: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments and command chains

52

check!that:!vodka!tastes!good

Page 119: What makes groovy groovy   codeurs en seine - 2013 - light size

Named arguments and command chains

52

check!that:!vodka!tastes!good

Will call:check(that: vodka).tastes(good)

Page 120: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Page 121: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »

Page 122: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Page 123: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Method returning a list

Page 124: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

53

def!(a,!b)!=!['A',!'B']

(a,!b)!=![b,!a]

def!(int!i,!int!j)!=![1,!2]

def!geocode(String!place)!{!!!!return![45.4,!2.3]}

def!(la,!lo)!=!geocode("Paris")

assert!la!==!45.4!&&!lo!==!2.3

Classic « swap »With types

Method returning a list

Destructuring

Page 125: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Page 126: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Method signature convention: getAt(int)

Page 127: What makes groovy groovy   codeurs en seine - 2013 - light size

Multiple assignment and destructuring

54

class!Point!{!!!!double!x,!y

!!!!double!getAt(int!idx)!{!!!!!!!!if!(idx!==!0)!x!!!!!!!!else!if!(idx!==!1)!y!!!!!!!!else!throw!new!Exception("Wrong!index")!!!!}}

def!(x,!y)!=!new!Point(x:!48.3,!y:!3.5)

assert!x!==!48.3!&&!y!==!3.5

Method signature convention: getAt(int)

Transparent destructuring

Page 128: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Page 129: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Page 130: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Closure blocks delimiting the structure

Page 131: What makes groovy groovy   codeurs en seine - 2013 - light size

Builders and GPath expressions

55

import!groovy.xml.*

new!MarkupBuilder().html!{!!!!head!{!!!!!!!!title!"The!Script!Bowl"!!!!}!!!!body!{!!!!!!!!div(class:!"banner")!{!!!!!!!!!!!!p!"Groovy!won!"!!!!!!!!}!!!!}}

Hierarchical data representation

Closure blocks delimiting the structure

Attributes

Page 132: What makes groovy groovy   codeurs en seine - 2013 - light size

Power asserts

56

def!(a,!b,!c)!=![20,!30,!40]

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1

Page 133: What makes groovy groovy   codeurs en seine - 2013 - light size

Power asserts

56

def!(a,!b,!c)!=![20,!30,!40]

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1

Assertion!failed:!

assert!a!*!(b!c!1)!/!10!==!3!*!c!/!2!+!1!!!!!!!|!|!!|!|!!!!|!!!!|!!!!|!|!|!!!|!!!!!!!|!580|!29!!!58!!!false|!|!60!!61!!!!!!!20!!!30!!!!!!!!!!!!!!!|!40!!!!!!!!!!!!!!!!!!!!!!!!!!!!!120

! at!script1.run(script1t.groovy:4)

Page 134: What makes groovy groovy   codeurs en seine - 2013 - light size

Null handling

• Groovy provides a more descriptive NullPointerException than Java

• Safe navigation with ?.

57

Page 135: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 136: What makes groovy groovy   codeurs en seine - 2013 - light size

The Truth, the Groovy Truth!

Page 137: What makes groovy groovy   codeurs en seine - 2013 - light size

The Truth, the Groovy Truth!

And what if I could customize the truth?

Page 138: What makes groovy groovy   codeurs en seine - 2013 - light size

?:

Page 139: What makes groovy groovy   codeurs en seine - 2013 - light size

The Elvis operator!

?:

Page 140: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

Page 141: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

Page 142: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!y

Page 143: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!y

Page 144: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!y

Page 145: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!y

Page 146: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y

Page 147: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Page 148: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Good old ternary operator

Page 149: What makes groovy groovy   codeurs en seine - 2013 - light size

Towards Elvis...

60

def!(x,!y)!=!['MacBook!Pro',!'unknown']

if*(x!!=!null!&&!x.size()!>!0)!x!else!yif*(x!&&!x.size())!x!else!yif*(x)!x!else!yx!?!x!:!yx!?:!y Null, empty, zero-

sized... false, otherwise true!

Good old ternary operatorElvis!

Page 150: What makes groovy groovy   codeurs en seine - 2013 - light size

AST transformations

• Abstract Syntax Tree– in memory representation of your program

before being compiled into bytecode

• AST transformation == process of transforming the AST of a program before it’s compiled

• Macro-like compiler hook!

61

Page 151: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Code generation

– @ToString, @EqualsAndHashCode, @Canonical, @TupleConstructor, @InheritConstructors, @Category, @IndexedProperty, @Lazy, @Newify

• Class design

– @Delegate, @Immutable, @Memoized, @Singleton, @Mixin

• Logging

– @Log, @Log4j, @Log4j2, @Slf4j

62

Page 152: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Safer scripting

– @ConditionalInterrupt, @ThreadInterrupt, @TimedInterupt

• Compiler directives

– @Field, @PackageScope, @AnnotationCollector, @DelegatesTo, @TypeChecked, @CompileStatic, @CompileDynamic

• Swing patterns

– @Bindable, @ListenerList, @Vetoable

63

Page 153: What makes groovy groovy   codeurs en seine - 2013 - light size

Lots of AST transformations...

• Dependencies handling

– @Grab, @GrabConfig, @GrabExclude, @GrabResolver

• Test assistance

– @NotYetImplemented, @ASTTest

64

Page 154: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• Implement immutability by the book

– final class– tuple-style constructor– private final backing fields– defensive copying of collections– equals() and hashCode() methods– toString() method– ...

65

Page 155: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• Implement immutability by the book

– final class– tuple-style constructor– private final backing fields– defensive copying of collections– equals() and hashCode() methods– toString() method– ...

65

Can be error-prone to write immutable classes oneself !

Page 156: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Page 157: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Damn verbose

Java!

Page 158: What makes groovy groovy   codeurs en seine - 2013 - light size

Immutability

• A Person class with– a String name– an int age

66

public final class Person { private final String name; private final int age;

public Person(String name, int age) { this.name = name; this.age = age; }

public String getName() { return name; }

public int getAge() { return age; }

public int hashCode() { return age + 31 * name.hashCode(); }

public boolean equals(Object other) { if (other == null) { return false; } if (this == other) { return true; } if (Person.class != other.getClass()) { return false; } Person otherPerson = (Person)other; if (!name.equals(otherPerson.getName()) { return false; } if (age != otherPerson.getAge()) { return false; } return true; }

public String toString() { return "Person(" + name + ", " + age + ")"; }}

Damn verbose

Java!

Although it’s also a valid Groovy program!

Page 159: What makes groovy groovy   codeurs en seine - 2013 - light size

@Immutable

67

import!groovy.transform.*

@Immutableclass!Person!{!!!!String!name!!!!int!age}

Page 160: What makes groovy groovy   codeurs en seine - 2013 - light size

Memoization

• Cache the result of previous invocations of closures or methods with the same set of argument values

68

import!groovy.transform.*

@Memoizedlong!fib(long!n)!{!!!!if!(n!==!0)!0!!!!else!if!(n!==!1)!1!!!!else!fib(n!c!1)!+!fib(n!c!2)}

println!fib(40)

Page 161: What makes groovy groovy   codeurs en seine - 2013 - light size

Memoization

• Cache the result of previous invocations of closures or methods with the same set of argument values

68

import!groovy.transform.*

@Memoizedlong!fib(long!n)!{!!!!if!(n!==!0)!0!!!!else!if!(n!==!1)!1!!!!else!fib(n!c!1)!+!fib(n!c!2)}

println!fib(40)

Best applied to side-effect free

functions

Page 162: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 163: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

Page 164: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

Page 165: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

More concise, more readable code

Page 166: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy allows you to be lazy

The compiler will do the job for you

More concise, more readable code

Less stuff to maintain and worry about

Page 167: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

Page 168: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

You can even extend the static type checker!

Page 169: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• Static type checking with @TypeChecked, throws compilation errors on...– typos in method and variable names– incompatible return types– wrong type assignments

• Supports fine-grained type inference– « Least Upper Bound »– « Flow typing »

70

You can even extend the static type checker!

Type check DSLs or dynamic features!

Page 170: What makes groovy groovy   codeurs en seine - 2013 - light size

@TypeChecked and @CompileStatic

• What is type checked can also be compiled statically with @CompileStatic

– generate the same bytecode as javac

– same performance as Java

71

Page 171: What makes groovy groovy   codeurs en seine - 2013 - light size

Static compilation performance

72

Fibonacci Pi (π) quadrature

Binarytrees

Java

Staticcompilation

Primitive optimizations

No prim.optimizations

191 ms 97 ms 3.6 s

197 ms 101 ms 4.3 s

360 ms 111 ms 23.7 s

2590 ms 3220 ms 50.0 s1.7

1.8

2.x

Page 172: What makes groovy groovy   codeurs en seine - 2013 - light size

Superb community!

Part 3

Page 173: What makes groovy groovy   codeurs en seine - 2013 - light size

A blossomingEcosystem

Page 174: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 175: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 176: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 177: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 178: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM

Page 179: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 180: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM

Page 181: What makes groovy groovy   codeurs en seine - 2013 - light size

GVMGROOVYENVIRONMENT

MANAGER

Page 182: What makes groovy groovy   codeurs en seine - 2013 - light size

GVM: Groovy enVironment Manager

• The new kid on the block– http://gvmtool.net/ — @gvmtool

• Manage parallel versions of the various ecosystem projects

• Supports...– Groovy, Grails, Griffon, Gradle, Vert.x, Spring Boot

• On Linux, MacOS, Cygwin, Solaris, FreeBSD81

Page 183: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 184: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

Page 185: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

...the Spock testing framework

Page 186: What makes groovy groovy   codeurs en seine - 2013 - light size

I’m Spock...

...the Spock testing framework

Page 187: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

Page 188: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Page 189: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Page 190: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Page 191: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Expression to be asserted

Page 192: What makes groovy groovy   codeurs en seine - 2013 - light size

Spock example

83

@Grab('org.spockframework:spockccore:0.7cgroovyc2.0')import!spock.lang.*

class!MathSpec!extends!Specification!{!!!!def!"maximum!of!two!numbers"()!{******expect:!!!!!!!!Math.max(a,!b)!==!c

******where:!!!!!!!!a!|!b!||!c!!!!!!!!1!|!3!||!3!!!!!!!!7!|!4!||!4!!!!!!!!0!|!0!||!0!!!!}}

@Grab a dependency

Meaningful test method names

Clever use of labels for BDD style

Expression to be assertedCute data-

driven tests!

Page 193: What makes groovy groovy   codeurs en seine - 2013 - light size
Page 194: What makes groovy groovy   codeurs en seine - 2013 - light size

@GrabResolver("https://oss.jfrog.org/artifactory/repo")@Grab("org.ratpackcframework:ratpackcgroovy:0.9.0cSNAPSHOT")import!static!org.ratpackframework.groovy.RatpackScript.ratpackimport!static!org.ratpackframework.groovy.Template.groovyTemplate

ratpack!{!!!!handlers!{!!!!!!!!get!{!!!!!!!!!!!!response.send!"Welcome!"!!!!!!!!}

!!!!!!!!get("date")!{!!!!!!!!!!!!render!groovyTemplate("date.html")!!!!!!!!}

!!!!!!!!assets!"public"!!!!}}

Page 195: What makes groovy groovy   codeurs en seine - 2013 - light size

@GrabResolver("https://oss.jfrog.org/artifactory/repo")@Grab("org.ratpackcframework:ratpackcgroovy:0.9.0cSNAPSHOT")import!static!org.ratpackframework.groovy.RatpackScript.ratpackimport!static!org.ratpackframework.groovy.Template.groovyTemplate

ratpack!{!!!!handlers!{!!!!!!!!get!{!!!!!!!!!!!!response.send!"Welcome!"!!!!!!!!}

!!!!!!!!get("date")!{!!!!!!!!!!!!render!groovyTemplate("date.html")!!!!!!!!}

!!!!!!!!assets!"public"!!!!}}

Lightweight Netty-based web app toolkit

Page 196: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb

• Browser automation solution

• WebDriver + jQuery selectors + Groovy

• Handy for– scripting, scraping, automation...– functional / web / acceptance testing

• when integrated with JUnit, TestNG or Spock

85

Page 197: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Page 198: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Page 199: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Page 200: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Page 201: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Submit the form

Page 202: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — Example

86

import!geb.Browser

Browser.drive!{!!!!go!"http://myapp.com/login"

!!!!assert!$("h1").text()!==!"Please!Login"

!!!!$("form.login").with!{!!!!!!!!username!=!"admin"!!!!!!!!password!=!"password"!!!!!!!!login().click()!!!!}

!!!!assert!$("h1").text()!==!!!!!!!!!"Admin!Section"}

Drive the browser to this site

Check the content of the title

Find & fill in the form

Submit the form

In the admin section, yeah!

Page 203: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

Page 204: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

Page 205: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

BDD style: given/when/then

Page 206: What makes groovy groovy   codeurs en seine - 2013 - light size

Geb — With page objects and Spock

87

import!geb.spock.GebSpec

class!GoogleWikipediaSpec!extends!GebSpec!{

!!!!def!"first!result!for!wikipedia!search!should!be!wikipedia"()!{********given:!!!!!!!!to!GoogleHomePage

********expect:!!!!!!!!at!GoogleHomePage

********when:!!!!!!!!search.field.value("wikipedia")

********then:!!!!!!!!waitFor!{!at!GoogleResultsPage!}

********and:!!!!!!!!firstResultLink.text()!==!"Wikipedia"

********when:!!!!!!!!firstResultLink.click()

********then:!!!!!!!!waitFor!{!at!WikipediaPage!}!!!!}}

With page objects

BDD style: given/when/then

Wait for slow loading pages

Page 207: What makes groovy groovy   codeurs en seine - 2013 - light size

Summary

Part 4

Page 208: What makes groovy groovy   codeurs en seine - 2013 - light size

Java’s best friend

• Java derived syntax– Flat learning curve– Easy to learn

• But goes beyond Java– Concise, expressive, readable– Fit for Domain-Specific Languages

• Seamless & transparent Java integration– Mix and match Groovy and Java classes (joint compil.)– No language barrier to cross

89

Page 209: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy’s nature

• Object oriented dynamic language...

• But...– as type safe as you want it — static type checking

– as fast as you need it — static compilation– as functional as you make it — closures...

90

Page 210: What makes groovy groovy   codeurs en seine - 2013 - light size

Groovy use cases

• Scripting tasks, build automation

• Extension points for customizing/configuring apps

• Business languages & Domain-Specific Languages

• Full blown apps

– for desktop with Griffon– for the web with Grails, Ratpack, Gaelyk– for web reactive programming with reactor

91