The document provides an overview of past and future developments for the Groovy programming language. It summarizes highlights from Groovy version 1.6, including performance improvements, new features like multiple assignments and annotation processing, and the addition of the Grape module system. It then previews new features for Groovy 1.7 such as anonymous inner classes, improved annotation handling, and tools for working with AST transformations. The presentation concludes by looking ahead to future versions 1.8 and beyond.
2. to infinity
and beyond!
Guillaume Laforge
SpringSource, a division of VMWare
mercredi 19 mai 2010
3. Guillaume Laforge
Groovy Project Manager
on Groovy since 2003!
JSR-241 Spec Lead
Head of Groovy Development
at 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
4. Agenda
Past
Groovy 1.6 flashback
Present
Groovy 1.7 novelties
A few Groovy 1.7.x refinements
Future
What’s cooking for 1.8 and beyond
mercredi 19 mai 2010
6. Big highlights of Groovy 1.6
Greater compile-time and runtime performance
Multiple assignments
Optional return for if/else and try/catch/finally
Java 5 annotation definition
AST Transformations
The Grape module and dependency system
Various Swing related improvements
JMX Builder
Metaprogramming additions
JSR-223 scripting engine built-in
Out-of-the-box OSGi support
mercredi 19 mai 2010
7. Multiple assignement
// multiple assignment
def (a, b) = [1, 2]
assert a == 1 && b == 2
// with typed variables
def (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
8. 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
9. 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
10. 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
11. @Immutable
To 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
12. Grab a grape!
Simple distribution and sharing of Groovy scripts
Dependencies stored locally
Can 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)
SIONS)
def ctx = new Context(srv , "/", SES
ctx.resourceBase = "."
ovy")
ctx.addServlet(GroovyServlet, "*.gro
srv.start()
}
mercredi 19 mai 2010
17. Big highlights of Groovy 1.7
Anonymous Inner Classes and Nested Classes
Annotations anywhere
Grape improvements
Power Asserts
AST Viewer
AST Builder
Customize the Groovy Truth!
Rewrite of the GroovyScriptEngine
Groovy Console improvements
SQL support refinements
mercredi 19 mai 2010
18. AIC and NC
Anonymous Inner Classe and Nested Classes
mercredi 19 mai 2010
19. AIC and NC
Anonymous Inner Classe and Nested Classes
For J ava
pa ste
co py’n
pa tibi lity
com
sak e :-)
mercredi 19 mai 2010
20. Annonymous Inner Classes
bo olean called = false
Timer ti mer = new Timer()
timer.schedule(n ew TimerTask() {
void run() {
called = true
}
}, 0)
sleep 100
assert called
mercredi 19 mai 2010
21. Annonymous Inner Classes
bo olean called = false
Timer ti mer = new Timer()
timer.schedule(n ew TimerTask() {
void run() {
called = true
}
{ called = true }
}, 0) as TimerTask
sleep 100
assert called
mercredi 19 mai 2010
22. Nested Classes
class Environment {
static class Production
extends Environment {}
static class Development
extends Environment {}
}
new Environment.Production()
mercredi 19 mai 2010
23. Anotations anywhere
You can now put annotations
on imports
on packages
on variable declarations
Examples with @Grab following...
mercredi 19 mai 2010
24. 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")
ion"
}.toString()).book.title == "Groovy in Act
mercredi 19 mai 2010
25. 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 {
nig")
book(title: "Groovy in Action", author: "Dierk Koe
}
assert books.toString() ==
'{"books":{"book":{"title":"Groovy in Action",' +
'"author":"Dierk Koenig"}}}'''
mercredi 19 mai 2010
26. Grape improvements (3/3)
Groovy 1.7 introduced Grab resolver
For when you need to specify a specific repository
for 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
27. Power Asserts (1/2)
Much better assert statement!
Invented and developed in the Spock framework
Given this script...
def energy = 7200 * 10**15 + 1
def mass = 80
def celerity = 300000000
assert energy == mass * celerity ** 2
mercredi 19 mai 2010
28. Power Asserts (2/2)
You’ll get a more comprehensible output
mercredi 19 mai 2010
30. Easier AST Transformations
AST Transformations are a very powerful feature
But are still rather hard to develop
Need 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
32. AST Builder
// Ability to build AST parts
// ‐‐> from a String
new AstBui lder().buildFromString(''' "Hello" ''')
// ‐‐> from code
new AstBuilder().buildFromCode { "Hello" }
// ‐‐> from a specification
{
List<ASTNo de> nodes = new AstBuilder().buildFromSpec
block {
returnStatement {
constant "Hello"
}
}
}
mercredi 19 mai 2010
33. Customize the Groovy Truth!
Ability to customize the truth by implementing a
boolean asBoolean() method
class Predicate {
boolean value
boolean asBoolean() { value }
}
def tr uePred = new Predicate(value: true)
def fals ePred = new Predicate(value: false)
assert truePred && !falsePred
mercredi 19 mai 2010
34. SQL support refinements
// batch statements
sql.withBatch { stmt ‐>
e ‐>
["Paul", "Jochen", "Guillaume"].each { nam e)"
stmt.addBat ch "insert into PERSON (name) values ($nam
}
}
// transaction support
def 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
35. 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
36. Map improvements
// map auto‐vification
def m = [:].withDefault { key ‐> "Default" }
assert m['z'] == "Default"
assert m['a'] == "Default"
// default sort
m.sort()
// sort with a comparator
m.sort({ a, b ‐> a <=> b } as Comparator)
mercredi 19 mai 2010
37. XML back to String
Ability 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.book
def bu ilder = new StreamingMarkupBuilder()
assert build er.bindNode(someNode).toString() ==
"<book isbn='12345'>Groovy in Action</book>"
mercredi 19 mai 2010
38. Currying improvements
// right currying
def divide = { a, b ‐> a / b }
def halver = divide.rcurry(2)
assert halver(8) == 4
// currying n‐th parameter
def jo inWithSeparator = { one, sep, two ‐>
one + sep + two
}
def joinWithComma =
jo inWithSeparator.ncurry(1, ', ')
assert joinWithComma('a', 'b') == 'a, b'
mercredi 19 mai 2010
39. New icon for the Swing console
mercredi 19 mai 2010
40. New icon for the Swing console
mercredi 19 mai 2010
45. What we’re working on
More 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
47. Closure annotations
Groovy 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
48. GContracts
Closures are already allowed in the Groovy 1.7
Antlr grammar
Andre Steingreß created GContracts,
a «design by contract» module
// a class invariant
@I nvariant({ name.size() > 0 && age > ageLimit() })
// a method pre‐condition
@Requires({ message != null })
// a method post‐condition
@Ensures({ returnResult % 2 == 0 })
mercredi 19 mai 2010
51. bu ild
dh oc oo vy
ore a lar Gr
M du s!
o
e m rom H an
Mor ef
M or
mercredi 19 mai 2010
52. More modular build
«Not everybody needs everything!» ™
A lighter Groovy-core
what’s in groovy-all?
Modules
test, jmx, swing, xml, sql, web, template
integration (bsf, jsr-223)
tools (groovydoc, groovyc, shell, console, java2groovy)
mercredi 19 mai 2010
53. Java 7 / JDK 7 / Project Coin
JSR-292 InvokeDynamic
Simple Closures?
Proposals from Project Coin
Strings 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
54. Improved DSL support
GEP-3: an extended command expression DSL
Groovy Extension Proposal #3
A Google Summer of Code student will work on that
Command expressions
basically top-level statements without parens
combine named and non-named arguments in the mix
for nicer Domain-Specific Languages
mercredi 19 mai 2010
55. Before GEP-3
The 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
56. With GEP-3
The 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
57. With GEP-3
The 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
Less
pare
take 2.pills of chloroquinine in 6.hours
& co ns
every 10.minutes execute { }
mm
given { } when { } then { } as
blend red, green of acrylic
mercredi 19 mai 2010
58. AST Templates
Since AST, it’s easier to write AST Transformations
But we can even do better!
Hamlet D’Arcy is working on a new proposal
GEP-4 — AST Templates
mercredi 19 mai 2010
60. Towards a new MOP?
The Meta-Object Protocol show its age
different stratification layers
DGM, categories, custom MetaClasses, ExpandoMetaClass...
different characteristics
scope: 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
61. Some potential modules
GPars was considered a potential module for
addition into core
but got a life of its own!
Parser combinators
for when you hit the walls of the Groovy syntax
and AST transformations won’t cut it
Pattern matching
mercredi 19 mai 2010
62. 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
63. Summary (1/2)
No need to wait for Java 7, 8, 9...
closures, properties, interpolated strings, extended
annotations, metaprogramming, [YOU NAME IT]...
oov y’s
Gr ive
no vat
sti ll in
20 03!
si nce
mercredi 19 mai 2010
64. 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
65. Thanks for your attention!
e
aforg pment
ume L Develo
Guilla Groovy om
He ad of e@ gmail.c
glaforg rge
Email: @glafo
:
Twitter
mercredi 19 mai 2010