67
to Infinity and Beyond mercredi 19 mai 2010

Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Embed Size (px)

Citation preview

Page 1: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

to Infinity and Beyond

mercredi 19 mai 2010

Page 2: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Guillaume LaforgeSpringSource, a division of VMWare

to infinity and beyond!

mercredi 19 mai 2010

Page 3: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Guillaume LaforgeGroovy Project Manager

on Groovy since 2003!

JSR-241 Spec Lead

Head of Groovy Developmentat SpringSource (division of VMWare)

Initiator of the Grails framework

Creator of the Gaelyk toolkit

Co-author of Groovy in Action

International speaker

mercredi 19 mai 2010

Page 4: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AgendaPast

Groovy 1.6 flashback

PresentGroovy 1.7 novelties

A few Groovy 1.7.x refinements

FutureWhat’s cooking for 1.8 and beyond

mercredi 19 mai 2010

Page 5: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

looking into the Pastmercredi 19 mai 2010

Page 6: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Big highlights of Groovy 1.6Greater compile-time and runtime performanceMultiple assignmentsOptional return for if/else and try/catch/finallyJava 5 annotation definitionAST TransformationsThe Grape module and dependency systemVarious Swing related improvementsJMX BuilderMetaprogramming additionsJSR-223 scripting engine built-inOut-of-the-box OSGi support

mercredi 19 mai 2010

Page 7: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Multiple assignement// multiple assignmentdef (a, b) = [1, 2]assert a == 1 && b == 2 // with typed variablesdef (int c, String d) = [3, "Hi"]assert c == 3 && d == "Hi" def geocode(String place) { [48.8, 2.3] }def lat, lng// assignment to existing variables(lat, lng) = geocode('Paris') // classical variable swaping example(a, b) = [b, a]

mercredi 19 mai 2010

Page 8: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

More optional return// optional return for if statements

def m1() {    if (true) 1    else 0}assert m1() == 1 // optional return for try/catch/finally

def m2(bool) {    try {        if (b) throw new Exception()

        1    } catch (any) { 2 }    finally { 3 }}assert m2(true) == 2 && m2(false) == 1

mercredi 19 mai 2010

Page 9: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AST Transformation (1/2)Groovy 1.6 introduced AST Transformations

AST: Abstract Syntax Tree

Ability to change what’s being compiled by the Groovy compiler... at compile time

No runtime impact!

Change the semantics of your programs! Even hijack the Groovy syntax!

Implementing recurring patterns in your code base

Remove boiler-plate code

Two kinds: global and local (triggered by anno)

mercredi 19 mai 2010

Page 10: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AST Transformations (2/2)Transformations introduced in 1.6

@Singleton

@Immutable, @Lazy, @Delegate

@Newify

@Category, @Mixin

@PackageScope

Swing’s @Bindable and @Vetoable

Grape’s own @Grab

mercredi 19 mai 2010

Page 11: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

@ImmutableTo properly implement immutable classes

No mutations — state musn’t change

Private final fields

Defensive copying of mutable components

Proper equals() / hashCode() / toString() for comparisons or fas keys in maps

@Immutable class Coordinates {    Double lat, lng}def c1 = new Coordinates(lat: 48.8, lng: 2.5)

def c2 = new Coordinates(48.8, 2.5)assert c1 == c2

mercredi 19 mai 2010

Page 12: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Grab a grape!Simple distribution and sharing of Groovy scripts

Dependencies stored locallyCan even use your own local repositories

@Grab(group   = 'org.mortbay.jetty',

      module  = 'jetty‐embedded',

      version = '6.1.0')

def startServer() {    def srv = new Server(8080)

    def ctx = new Context(srv , "/", SESSIONS)

    ctx.resourceBase = "."

    ctx.addServlet(GroovyServlet, "*.groovy")

    srv.start()}

mercredi 19 mai 2010

Page 13: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Metaprogramming additions (1/2)ExpandoMetaClass DSL

factoring EMC changes

Number.metaClass {    multiply { Amount amount ‐>         amount.times(delegate)     }    div { Amount amount ‐>         amount.inverse().times(delegate) 

    }}

mercredi 19 mai 2010

Page 14: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Metaprogramming additions (2/2)Runtime mixins

class FlyingAbility {    def fly() { "I'm ${name} and I fly!" }

} class JamesBondVehicle {    String getName() { "James Bond's vehicle" }

} JamesBondVehicle.mixin FlyingAbility

 assert new JamesBondVehicle().fly() ==

    "I'm James Bond's vehicle and I fly!"

mercredi 19 mai 2010

Page 15: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

JMX BuilderA DSL for handling JMX

in addition of Groovy MBean// Create a connector serverdef jmx = new JmxBuilder()jmx.connectorServer(port:9000).start()

 // Create a connector clientjmx.connectorClient(port:9000).connect()

 //Export a beanjmx.export { bean new MyService() } // Defining a timerjmx.timer(name: "jmx.builder:type=Timer", 

    event: "heartbeat", period: "1s").start()

 // JMX listenerjmx.listener(event: "someEvent", from: "bean", 

    call: { evt ‐> /* do something */ })

mercredi 19 mai 2010

Page 16: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

into the Present...mercredi 19 mai 2010

Page 17: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Big highlights of Groovy 1.7Anonymous Inner Classes and Nested ClassesAnnotations anywhereGrape improvementsPower AssertsAST ViewerAST BuilderCustomize the Groovy Truth!Rewrite of the GroovyScriptEngineGroovy Console improvementsSQL support refinements

mercredi 19 mai 2010

Page 18: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AIC and NCAnonymous Inner Classe and Nested Classes

mercredi 19 mai 2010

Page 19: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AIC and NCAnonymous Inner Classe and Nested Classes

For Java

copy’n paste

compatibility

sake :-)

mercredi 19 mai 2010

Page 20: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Annonymous Inner Classes

boolean called = false

Timer timer = new Timer()

timer.schedule(new TimerTask() {

    void run() {

        called = true

    }}, 0)

sleep 100assert called

mercredi 19 mai 2010

Page 21: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Annonymous Inner Classes

boolean called = false

Timer timer = new Timer()

timer.schedule(new TimerTask() {

    void run() {

        called = true

    }}, 0)

sleep 100assert called

{ called = true } as TimerTask

mercredi 19 mai 2010

Page 22: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Nested Classes

class Environment {    static class Production         extends Environment {}

    static class Development         extends Environment {}

} new Environment.Production()

mercredi 19 mai 2010

Page 23: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Anotations anywhere

You can now put annotationson imports

on packages

on variable declarations

Examples with @Grab following...

mercredi 19 mai 2010

Page 24: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Grape improvements (1/3)@Grab on import

@Grab(group = 'net.sf.json‐lib', 

     module = 'json‐lib', 

    version = '2.3', classifier = 'jdk15')import net.sf.json.groovy.*

 assert new JsonSlurper().parseText(

new JsonGroovyBuilder().json {

    book(title: "Groovy in Action", 

        author:"Dierk König et al")

}.toString()).book.title == "Groovy in Action"

mercredi 19 mai 2010

Page 25: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Grape improvements (2/3)Shorter module / artifact / version parameter

Example of an annotation on a variable declaration

@Grab('net.sf.json‐lib:json‐lib:2.3:jdk15')

def builder = new net.sf.json.groovy.JsonGroovyBuilder()

def books = builder.books {    book(title: "Groovy in Action", author: "Dierk Koenig")

}assert books.toString() ==    '{"books":{"book":{"title":"Groovy in Action",' + 

    '"author":"Dierk Koenig"}}}'''

mercredi 19 mai 2010

Page 26: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Grape improvements (3/3)Groovy 1.7 introduced Grab resolver

For when you need to specify a specific repositoryfor a given dependency

@GrabResolver(    name = 'restlet.org',    root = 'http://maven.restlet.org')

@Grab('org.restlet:org.restlet:1.1.6')

import org.restlet.Restlet

mercredi 19 mai 2010

Page 27: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Power Asserts (1/2)Much better assert statement!

Invented and developed in the Spock framework

Given this script...

def energy = 7200 * 10**15 + 1def mass = 80def celerity = 300000000 assert energy == mass * celerity ** 2

mercredi 19 mai 2010

Page 28: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Power Asserts (2/2)You’ll get a more comprehensible output

mercredi 19 mai 2010

Page 29: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Spock testing framework

mercredi 19 mai 2010

Page 30: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Easier AST TransformationsAST Transformations are a very powerful feature

But are still rather hard to developNeed to know the AST API closely

To help with authoring your own transformations, we’ve introduced

the AST Viewer in the Groovy Console

the AST Builder

mercredi 19 mai 2010

Page 31: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AST Viewer

mercredi 19 mai 2010

Page 32: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AST Builder

// Ability to build AST parts

// ‐‐> from a Stringnew AstBuilder().buildFromString(''' "Hello" '''

)

 // ‐‐> from codenew AstBuilder().buildFromCode { "Hello" }

 // ‐‐> from a specification

List<ASTNode> nodes = new AstBuilder().buildFromSpec {

    block {        returnStatement {

            constant "Hello"

        }    }}

mercredi 19 mai 2010

Page 33: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Customize the Groovy Truth!Ability to customize the truth by implementing a boolean asBoolean() method

class Predicate {    boolean value    boolean asBoolean() { value }

} def truePred  = new Predicate(value: true)

def falsePred = new Predicate(value: false)

 assert truePred && !falsePred

mercredi 19 mai 2010

Page 34: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

SQL support refinements

// batch statementssql.withBatch { stmt ‐>

["Paul", "Jochen", "Guillaume"].each { name ‐>

 stmt.addBatch "insert into PERSON (name) values ($name)"

}} // transaction supportdef persons = sql.dataSet("person")

sql.withTransaction {  persons.add name: "Paul"  persons.add name: "Jochen"

  persons.add name: "Guillaume"

  persons.add name: "Roshan"

}

mercredi 19 mai 2010

Page 35: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Groovy 1.7.x changes

Groovy 1.7.1 and 1.7.2 have been released

Groovy 1.7.3 is coming soon

Here’s what’s new!

mercredi 19 mai 2010

Page 36: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Map improvements

// map auto‐vificationdef m = [:].withDefault { key ‐> "Default" }

assert m['z'] == "Default" 

assert m['a'] == "Default"

// default sortm.sort()

// sort with a comparatorm.sort({ a, b ‐> a <=> b } as Comparator)

mercredi 19 mai 2010

Page 37: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

XML back to StringAbility to retrieve the XML string from a node from an XmlSlurper GPathResult

def xml = """<books>    <book isbn="12345">Groovy in Action</book>

</books>"""def root = new XmlSlurper().parseText(xml)

def someNode = root.bookdef builder = new StreamingMarkupBuilder()

assert builder.bindNode(someNode).toString() ==

        "<book isbn='12345'>Groovy in Action</book>"

mercredi 19 mai 2010

Page 38: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Currying improvements

// right curryingdef divide = { a, b ‐> a / b }

def halver = divide.rcurry(2)

assert halver(8) == 4 // currying n‐th parameterdef joinWithSeparator = { one, sep, two ‐>

    one + sep + two}def joinWithComma =     joinWithSeparator.ncurry(1, ', ')

assert joinWithComma('a', 'b') == 'a, b'

mercredi 19 mai 2010

Page 39: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

New icon for the Swing console

mercredi 19 mai 2010

Page 40: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

New icon for the Swing console

mercredi 19 mai 2010

Page 41: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

New String methodsprintln """    def method() {        return 'bar'    }""".stripIndent()

println """    |def method() {    |    return 'bar'    |}""".stripMargin('|')

// string "translation" (UNIX tr)

assert 'hello'.tr('z‐a', 'Z‐A') == 'HELLO'

assert 'Hello World!'.tr('a‐z', 'A') == 'HAAAA WAAAA!'

assert 'Hello World!'.tr('lloo', '1234') == 'He224 W4r2d!'

// capitalize the first letter

assert 'h'.capitalize() == 'H'

assert 'hello'.capitalize() == 'Hello'

assert 'hello world'.capitalize() == 'Hello world'

// tab/space (un)expansion (UNIX expand command)

assert '1234567\t8\t '.expand() == '1234567 8        '

assert '    x    '.unexpand() == '    x\t '

mercredi 19 mai 2010

Page 42: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

...and beyond!mercredi 19 mai 2010

Page 43: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Groovy 1.8 & beyondStill subject to discussion

Always evolving roadmap

Things may change!

mercredi 19 mai 2010

Page 44: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

What’s cooking?mercredi 19 mai 2010

Page 45: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

What we’re working onMore runtime performance improvements

Closure annotations

Gradle build

Modularizing Groovy

Align with JDK 7 / Java 7 / Project Coin

Enhanced DSL support

AST Templates

Towards MOP 2

mercredi 19 mai 2010

Page 46: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

«Blackdrag» revealedthe black magic!

mercredi 19 mai 2010

Page 47: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Closure annotationsGroovy 1.5 brought Java 5 annotations

What if... we could go beyond what Java offered?In 1.7, we can put annotations on packages, imports and variable declarations

But annotations are still limited in terms of parameters they allow

Here comes closure annotations!Groovy 1.8 will give us the ability to access annotation with closure parameters at runtime

mercredi 19 mai 2010

Page 48: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

GContractsClosures are already allowed in the Groovy 1.7 Antlr grammar

Andre Steingreß created GContracts, a «design by contract» module

// a class invariant@Invariant({ name.size() > 0 && age > ageLimit() })

 // a method pre‐condition@Requires({ message != null }) // a method post‐condition@Ensures({ returnResult % 2 == 0 })

mercredi 19 mai 2010

Page 49: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

mercredi 19 mai 2010

Page 50: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

mercredi 19 mai 2010

Page 51: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

More adhoc build

More modular Groovy

More from Hans!

mercredi 19 mai 2010

Page 52: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

More modular build«Not everybody needs everything!» ™

A lighter Groovy-corewhat’s in groovy-all?

Modulestest, jmx, swing, xml, sql, web, template

integration (bsf, jsr-223)

tools (groovydoc, groovyc, shell, console, java2groovy)

mercredi 19 mai 2010

Page 53: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Java 7 / JDK 7 / Project CoinJSR-292 InvokeDynamic

Simple Closures?

Proposals from Project CoinStrings in switch

Automatic Resource Management

Improved generics type inference (diamond <>)

Simplified varargs method invocation

Better integral literals

Language support for collections

mercredi 19 mai 2010

Page 54: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Improved DSL support

GEP-3: an extended command expression DSLGroovy Extension Proposal #3

A Google Summer of Code student will work on that

Command expressionsbasically top-level statements without parens

combine named and non-named arguments in the mixfor nicer Domain-Specific Languages

mercredi 19 mai 2010

Page 55: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Before GEP-3The idea: extend command-expressions, beyond top-level statements, for chained method calls

Before

send("Hello").to("Jochen")send("Hello", from: "Guillaume").to("Jochen")

sell(100.shares).of(MSFT)

take(2.pills).of(chloroquinine).in(6.hours)

every(10.minutes).execute {  }

given { }.when { }.then { }

blend(red, green).of(acrylic)

mercredi 19 mai 2010

Page 56: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

With GEP-3The idea: extend command-expressions, beyond top-level statements, for chained method calls

After

send "Hello"  to "Jochen"send "Hello", from: "Guillaume"  to "Jochen"

sell 100.shares  of MSFT

take 2.pills  of chloroquinine  in 6.hours

every 10.minutes  execute {  }

given { } when { } then { }

blend red, green  of acrylic

mercredi 19 mai 2010

Page 57: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

With GEP-3The idea: extend command-expressions, beyond top-level statements, for chained method calls

After

send "Hello"  to "Jochen"send "Hello", from: "Guillaume"  to "Jochen"

sell 100.shares  of MSFT

take 2.pills  of chloroquinine  in 6.hours

every 10.minutes  execute {  }

given { } when { } then { }

blend red, green  of acrylic

Less parens& commas

mercredi 19 mai 2010

Page 58: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

AST TemplatesSince AST, it’s easier to write AST Transformations

But we can even do better!

Hamlet D’Arcy is working on a new proposalGEP-4 — AST Templates

mercredi 19 mai 2010

Page 59: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

a new

MOP

mercredi 19 mai 2010

Page 60: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Towards a new MOP?The Meta-Object Protocol show its age

different stratification layersDGM, categories, custom MetaClasses, ExpandoMetaClass...

different characteristicsscope: global, local, thread-bound

works across the hierarchy or not

A better MOP could...help for performance

offer more granularity

let the developer choose the characteristics he needs

provide a layered approach of changes

mercredi 19 mai 2010

Page 61: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Some potential modulesGPars was considered a potential module for addition into core

but got a life of its own!

Parser combinatorsfor when you hit the walls of the Groovy syntax

and AST transformations won’t cut it

Pattern matching

mercredi 19 mai 2010

Page 62: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Summary (1/2)No need to wait for Java 7, 8, 9...

closures, properties, interpolated strings, extended annotations, metaprogramming, [YOU NAME IT]...

mercredi 19 mai 2010

Page 63: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Summary (1/2)No need to wait for Java 7, 8, 9...

closures, properties, interpolated strings, extended annotations, metaprogramming, [YOU NAME IT]...

Groovy’s

still innovative

since 2003!

mercredi 19 mai 2010

Page 64: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Summary (2/2)But it’s more than just a language, it’s a very rich and active ecosystem!

Grails, Griffon, Gradle, GPars, Spock, Gaelyk...

mercredi 19 mai 2010

Page 66: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Questions & Answers

mercredi 19 mai 2010

Page 67: Groovy to infinity and beyond - GR8Conf Europe 2010 - Guillaume Laforge

Images used in this presentationHouse / past: http://www.flickr.com/photos/jasonepowell/3680030831/sizes/o/

Present clock: http://www.flickr.com/photos/38629278@N04/3784344944/sizes/o/

Future: http://www.flickr.com/photos/befuddledsenses/2904000882/sizes/l/

Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/

Black dragon: http://www.free-computer-wallpapers.com/pictures/Fantasy-wallpaper/Black_Dragon

Puzzle: http://www.everystockphoto.com/photo.php?imageId=263521

Light bulb: https://newsline.llnl.gov/retooling/mar/03.28.08_images/lightBulb.png

Spock: http://altoladeira.files.wordpress.com/2009/07/spock2.jpg

mercredi 19 mai 2010