An Introduction to Groovy
Coding Serbia, 17.10.2013
Joachim Baumann
Agenda– Tour de Force

• 
• 
• 

The Language
Use Cases
Everything is an Object

• 
• 
• 

Collections: Ranges, Lists and Maps
Control Structures
Operator Overloading

• 

Closures: Higher-Order Functions

• 

Categories: Extending Classes at Runtime

• 

Examples
Groovy
• 

Is a
–  Scripting Language
–  Regular Programming Language

• 

Is derived from Java

• 

Is a dynamic language

• 

Is officially defined in the Java Community Process
–  JSR-241 (Java Specification Request)

• 

Is executed on a standard Java Virtual Machine

• 
• 
• 

Exists since 2003 (It is de facto an old language)
Is in the Top 20 list of TIOBE
Current version is 2.1.8
An Example (Java)
public class HelloWorld {
public static void main(String [ ] args) {
System.out.println(„HelloWorld“);
}
}

• 

The Simplest existing Java Program
An Example (Groovy)

println „Hello World“

Hello World

Comment: The example on the previous page is correct Groovy code also
Use Cases
• 

Programming of Scripts instead of
–  Sh, Perl, Python, Ruby …

• 

Unit-Tests
–  Much simpler way of writing test cases
–  Direct support for stub and mock objects

• 

Full-blown Applications
–  Frameworks
•  Grails as a Web-Application Framework
•  Griffon as a Swing-Application Framework

• 

Integration in large Applications
–  As Glue Code
–  Class-by-Class Substitution for Java e.g. in Spring
–  As Configuration Language
–  As Domain-Specific Language
Language Features

•  Very similar to Java
–  Easy to learn
–  In fact, every Java Program is a valid Groovy program
–  Java Object Model is used
•  Groovy tries to follow the principle of least surprise
•  All Java classes and frameworks can be used
–  High number of existing frameworks
•  Translated Groovy classes can be used by Java
–  Integration in both directions
•  Typing
–  Strong or weak
–  Dynamic or static
Everything is an Object
• 

Java differentiates primitive data types and objects
–  Original motivation were performance problems
–  Leads to impedance mismatch
• 

• 

translate “problems”

In Groovy everything is an Object
–  Numbers are objects as well

5.times { println „Hallo Welt“ }

Hallo Welt
Hallo Welt
Hallo Welt
Hallo Welt
Hallo Welt
Explicit Typing is optional
• 

Duck Typing
–  Known from Scripting languages

• 

Simplifies Programming

• 

We do not need to provide the type of a variable

• 

Under the hood Groovy uses explicit Typing

def a = 1

a is of Type Integer (simplified)
Collections
• 

Groovy adds a new Collection Type
–  Range

• 

And adds a lot of syntactic sugar for existing Collection Types
–  Lists
–  Maps

• 

Furthermore, the interfaces are harmonized
–  Example
Method size()
Collections: Range (a special variant of List)
•  Define a number of elements (a range) in an interval
1..5

Inclusive: Range 1 - 5

•  Ranges are Objects
def r = 1..<5

Exclusive: Range 1 - 4

•  We can iterate through all elements
r.each { n -> println n }

1
2
3
4

•  Elements are only created on demand
•  Classes implementing the Interface Comparable and providing the methods next()
und previous(), can be used in Ranges.
Collections: Lists
• 

Simplified Notation (extends the Java-Type List)

def list = [1, 2]
• 

Adding and Removing Values

list += 3
list = list - [2]
• 

We can iterate over the elements

list.each { n -> println n }
• 

[1, 2, 3]
[1, 3]

1
3

Subscript operator is supported (as with Ranges)
Collections: Maps
• 

Simplified Notation ( extends the Java-Type Map)

def map = [ „name“: „Groovy“, „typ“: „Language“ ]
• 

Accessing Elements

map.each { entry -> println „$entry.key: $entry.value“}
map [„name“] = „English“
• 

Shortened Access

println map.name

English

name: Groovy
typ: Language
Control Structures

• 

New For Loop Syntax

for ( i in 1..5 )
println „Hello $i“

Hello 1
Hello 2
Hello 3
Hello 4
Hello 5

• 

Every normal Java control structure is supported (including For Loops)

• 

Boolean decision much more general through the use of
Groovy Truth
Coercion of Collections, Iterators, Enumerations, Maps, Matchers, Strings,
Numbers and Object References to a boolean expression
Control Structures: Switch Statement
• 

Switch much more general than Java
(Example with Type, Range and Closure)

switch ( val ) {
case { it > 3 }: println „$val is larger than 3“; break
case 5..9:

println „$val is in the Range 5 – 9“; break

case Number: println „$val is of Type Number “; break
}
Operator-Overloading(1)
• 

Impossible in Java

• 

Widely used in Groovy

• 

Provided for many existing Java classes

• 

Works by implementing the respective Method
Example
Operator +
Operator …

• 

Method plus()
Method minus()

Thus your own implementations are straightforward
Operator Overloading(2)
class Complex {
BigDecimal r
BigDecimal i
def plus (Complex c) {
new Complex (r : this.r + c.r, i : this.i + c.i)
}
}
def res = new Complex(r:1, i:-1) + new Complex (r:1, i:1)
println "$res.r + $res.i i"
2+0i
Closures: Higher-Order Functions
• 

Basic Idea: Methods are Objects
–  Known from functional programming
–  There we have first-order (and higher-order) functions

• 

Anonymous inner classes on Steroids

• 

Usage
–  Separation of Concerns
•  Separation of Iteration and Logic
•  Central Resource Handling
–  Functional Programming Approaches
Closures: Definition (1)
• 

We have met (anonymous) Closures already

map.each { entry -> println „$entry.key: $entry.value“}
case { it > 3 }:
• 

println „$val is larger than 3“

General Definition

def c = { p1, p2, p3 = 0 ->
[ Source of the Closure]
}

Parameters can accept Default Values
If no Parameter is given, then
Implicit Parameter it
Return Value is the Result of the
last statement
Closures: Example
def square = { x -> x * x }
4

println square(2)
r = 1..5
r.each { println square(it) }

1
4
9
16
25

def cubed = { x -> x * square (x) }
r.each { println cubed(it) }
Implicit Parameter it

1
8
27
64
125
Closures: Functional Programming (1)
• 

Definition
„In mathematics and computer science, currying is the technique of transforming a
function that takes multiple arguments (or a tuple of arguments) in such a way that
it can be called as a chain of functions, each with a single argument (partial
application). It was originated by Moses Schönfinkel and later re-discovered by
Haskell Curry. Because of this, some say it would be more correct to name it
schönfinkeling. “
– Wikipedia

• 

Fixes the number of arguments to a function, thereby generating a new function

• 

Allows the concatenation of functions
Closures: Functional Programming (2)

def mul = { x, y -> x * y }
def mul2 = mul.curry(2)
def mul5 = mul.curry(5)
println mul2(3)
println mul5(2)

Equals { y -> 2 * y }
Equals { y -> 5 * y }
6
10

def komp = { g, f, x -> g( f(x) ) }
def mul10 = komp.curry(mul2, mul5)
println mul10(5)
// Left Shift Operator
mul10 = mul2 << mul5
println mul10(5)

g°f (x) := g(f(x))
Currying with Closures
50
Extending existing Classes using Categories

• 
• 
• 

Third-party Classes sometimes need to be extended or changed
Categories change behaviour of Objects and Classe at Runtime
Adding or Changing Methods

class HelloCategory {
public static String hello(String i) { return "Hello, $i" }
}
def testString = "Joachim"
use(HelloCategory) {
println testString.hello()
}

Hello, Joachim
Examples

• 

XML parsing

• 

A Web Server

• 

A Web Browser

• 

Domain-Specific Languages
Example XML-Parsing: An XML-Structure
<groovy>
<music>
<tune>
<title>The 59th Street Bridge Song</title>
<artist>Simon and Garfunkel</artist>
</tune>
<tune>
<title>Monday Monday</title>
<artist>The Mamas and The Papas</artist>
</tune>
<tune>
<title>Goodnight Moon</title>
<artist>Shivaree</artist>
</tune>
<tune>
<title>Suddenly</title>
<artist>Soraya</artist>
</tune>
</music>
</groovy>
XML-Parsing: The Groovy Script and the Output
Reference to XML-Tree
(equivalent to the root element groovy)
The Script
result = new XmlSlurper().parse(new File(args[0]))
result.music.tune.each {
elem -> println "$elem.title, $elem.artist"
}

The Output
The 59th Street Bridge Song, Simon and Garfunkel
Monday Monday, The Mamas and The Papas
Goodnight Moon, Shivaree
Suddenly, Soraya

GPath
Expression
Example: WebServer (25 Lines)
def webPath = args[0]
def getPattern = /GET (/?[^? ]*)??([^ ]+)?s+HTTP/[.d]+/
def server = new ServerSocket(5926)
while(true) {
server.accept() { socket ->
socket.withStreams { input, output ->
def line, resource
def reader = input.newReader()
while(line = reader.readLine()) {
println line
def match = line =~ getPattern
if(match)
resource = match[0][1]
}
def f = new File ("$webPath/$resource")
if(f.directory)
f = "$webPath/$resource/index.html" as File
if(!f.exists())
f = "$webPath/error.html" as File

}

output << "HTTP/1.0 200 OKn" //{{9}}
output << "Content-Type: text/htmlnn"
output << f.asWritable()
} }
Web-Browser
import groovy.swing.SwingBuilder
import javax.swing.event.HyperlinkEvent
urlAction = { swing.pane.page = new URL(it.actionCommand) }
hyperlinkAction = { evt ->
if(evt.eventType == HyperlinkEvent.EventType.ACTIVATED)
tf.text = swing.pane.page = evt.URL
}
swing = new SwingBuilder()
swing.frame(title: 'Mini-Browser', size: [900, 600],
windowClosing: { System.exit(0) } ) {
borderLayout()
panel (constraints: java.awt.BorderLayout.NORTH) {
tf = textField(columns: 50,
actionPerformed: urlAction)
}
scrollPane {
editorPane(editable: false, id: 'pane',
hyperlinkUpdate: hyperlinkAction,
constraints: java.awt.BorderLayout.SOUTH,
page: new URL("http://www.spiegel.de"))
}
}.show()
Example Domain Specific Language
• 

(Simplified) Language focusing on a specific problem area

• 

Used by Domain Experts, not necessarily IT-Personnel

• 

Focuses on the Problem Domain

• 

Allows a natural and succinct expression of problems in the problem domain

• 

Two Approaches
–  Internal DSL
–  External DSL

• 

Simple examples for a DSL
3.€ + 4.$ + 10.Yen
2.km + 5.mm + 3.yd+ 2.mi
DistanceDSL: The Class Unit
class Unit {
def ratio
String name
public static final mm = new Unit(ratio : 0, name : "millimeter")
public static final cm = new Unit(ratio : 1, name : "centimeter")
// equivalent Entries for m, km, yd, mi
…
static def convertUnit(Distance d, Unit newUnit) {
def factor = ratioTable[d.unit.ratio][newUnit.ratio]
if(factor)
return d.length * factor
else
return d.length / ratioTable[newUnit.ratio][d.unit.ratio]
}
static ratioTable = [
//
mm,
cm,
m,
km, y, mi
[
1,
0,
0,
0,
0, 0 ],
[
10,
1,
0,
0,
0, 0 ],
// äquivalente Einträge für m, km, yd, mi
…
]
}

// mm
// cm
DistanceDSL: The Class Distance
class Distance implements Comparable {
BigDecimal length
Unit unit
Distance plus(Distance operand) {
def newLength = this.length + Unit.convertUnit(operand, this.unit)
new Distance(length : newLength, unit : this.unit)
}
Distance minus(Distance operand) {
def newLength = this.length - Unit.convertUnit(operand, this.unit)
new Distance(length : newLength, unit : this.unit)
}
int compareTo(other) {
if(this.unit == other.unit)
return this.length <=> other.length
return this.length <=> Unit.convertUnit(other, this.unit)
}
String toString() {
"$length $unit.name"
}
}
DistanceDSL: The Category
class DistanceCategory {
static Distance getMm(Number n) {
new Distance(length : n, unit : Unit.mm)
}
static Distance getMm(Distance d) {
new Distance(length : Unit.convertUnit(d, Unit.mm), unit : Unit.mm)
}
…
Equivalent Lines for getCm(), getM(), getKm(), getYd(), getMi()
}
DistanceDSL: Result
use(DistanceCategory.class) {
def
def
def
def

d1
d2
d3
d4

println
println
println
println
println
println
println
println
}

=
=
=
=

1.m
1.yd
1760.yd
100.cm

1.m + 1.yd
1.yd + 1.mi
1.m - 1.yd
d2.m
d3.mi
d4.m
1000.yd.km
1000.yd < 1.km

1.9144	
  meter	
  
1761	
  yard	
  
0.0856	
  meter	
  
0.9144	
  meter	
  
1	
  mile(s)	
  
1	
  meter	
  
0.9144000	
  kilometer	
  
true	
  
Meta Object Protocol (1)

• 

Normally an Object has a fixed set of methods and properties (or interface)

• 

What happens if the Object can decide each time how to interpret a method call or
property access?

• 

Allows sensible reaction to calls that are not known at implementation time
Meta Object Protocol (2): A Simple Example
•  React to a call to a method that is not implemented
wird aufgerufen für alle nicht
implementierten Methoden
class MOPBeispiel {
public invokeMethod(String method, Object params) {
println "I have been called with $method()"
}
}
bsp = new MOPBeispiel()
bsp.helloWorld()
I have been called with helloWorld
Groovy: Is it worth it?
Interlude: The mythical Man-Month
Book written in the 70‘s, Author Frederick P. Brooks, Jr.
Contains basic wisdom of project management that is still not followed

In this context interesting
• 

Use of Higher Abstractions leads to a Growth in Productivity by a Factor, not by
a percentage (p. 186)
–  Classical Example is Assembler vs. C

• 

Introduction of new Languages: In the Beginning High Cost, Wins are reaped
later (p. 221

• 

Learning the Vocabulary – i.e., the frameworks and libraries – is timeconsuming (p. 224)
–  Example Java vs. C#
Groovy: Is it worth it?
•  Language provides Higher Abstractions than Java
•  Pro: Groovy is fully compatible to Java
–  Java Developers can use Groovy at once
–  Every Library and Framework is directly available
•  Con: Runtime Performance is lower. But
–  Call Site Caching allows Speed-Ups
–  Java 1.7 provides new VM-Byte-Code that allows this extremely fast
–  Difference is small (typically 1.5)
–  Groovy provides static compilation that leads to faster code
–  Critical parts of the Application can be written in Java
•  Groovy is the dynamic language with the lowest cost for introduction and usage
What didn’t we look into?
• 

GPath

• 

Unit-Tests und Mock-Objekte

• 

Groovy SQL

• 

Grails, GORM

• 

GString

• 

Bean-Unterstützung

• 

Reguläre Ausdrücke

• 

Builder-Unterstützung

• 

Generics

• 

Annotations

• 

AST Transformations

• 

…
More Information

•  Website
http://groovy.codehaus.org

•  The Definitive Book
„Groovy in Action“, Dierk König, Manning Publishing
http://www.manning.com/koenig

•  Lot of additional books in many languages
Questions?

Dr. Joachim Baumann
codecentric AG
An der Welle 4
60322 Frankfurt
joachim.baumann@codecentric.de
www.codecentric.de
blog.codecentric.de

Datum/ Fragen

40	
  

Introduction to Groovy (Serbian Developer Conference 2013)

  • 1.
    An Introduction toGroovy Coding Serbia, 17.10.2013 Joachim Baumann
  • 2.
    Agenda– Tour deForce •  •  •  The Language Use Cases Everything is an Object •  •  •  Collections: Ranges, Lists and Maps Control Structures Operator Overloading •  Closures: Higher-Order Functions •  Categories: Extending Classes at Runtime •  Examples
  • 3.
    Groovy •  Is a –  ScriptingLanguage –  Regular Programming Language •  Is derived from Java •  Is a dynamic language •  Is officially defined in the Java Community Process –  JSR-241 (Java Specification Request) •  Is executed on a standard Java Virtual Machine •  •  •  Exists since 2003 (It is de facto an old language) Is in the Top 20 list of TIOBE Current version is 2.1.8
  • 4.
    An Example (Java) publicclass HelloWorld { public static void main(String [ ] args) { System.out.println(„HelloWorld“); } } •  The Simplest existing Java Program
  • 5.
    An Example (Groovy) println„Hello World“ Hello World Comment: The example on the previous page is correct Groovy code also
  • 6.
    Use Cases •  Programming ofScripts instead of –  Sh, Perl, Python, Ruby … •  Unit-Tests –  Much simpler way of writing test cases –  Direct support for stub and mock objects •  Full-blown Applications –  Frameworks •  Grails as a Web-Application Framework •  Griffon as a Swing-Application Framework •  Integration in large Applications –  As Glue Code –  Class-by-Class Substitution for Java e.g. in Spring –  As Configuration Language –  As Domain-Specific Language
  • 7.
    Language Features •  Verysimilar to Java –  Easy to learn –  In fact, every Java Program is a valid Groovy program –  Java Object Model is used •  Groovy tries to follow the principle of least surprise •  All Java classes and frameworks can be used –  High number of existing frameworks •  Translated Groovy classes can be used by Java –  Integration in both directions •  Typing –  Strong or weak –  Dynamic or static
  • 8.
    Everything is anObject •  Java differentiates primitive data types and objects –  Original motivation were performance problems –  Leads to impedance mismatch •  •  translate “problems” In Groovy everything is an Object –  Numbers are objects as well 5.times { println „Hallo Welt“ } Hallo Welt Hallo Welt Hallo Welt Hallo Welt Hallo Welt
  • 9.
    Explicit Typing isoptional •  Duck Typing –  Known from Scripting languages •  Simplifies Programming •  We do not need to provide the type of a variable •  Under the hood Groovy uses explicit Typing def a = 1 a is of Type Integer (simplified)
  • 10.
    Collections •  Groovy adds anew Collection Type –  Range •  And adds a lot of syntactic sugar for existing Collection Types –  Lists –  Maps •  Furthermore, the interfaces are harmonized –  Example Method size()
  • 11.
    Collections: Range (aspecial variant of List) •  Define a number of elements (a range) in an interval 1..5 Inclusive: Range 1 - 5 •  Ranges are Objects def r = 1..<5 Exclusive: Range 1 - 4 •  We can iterate through all elements r.each { n -> println n } 1 2 3 4 •  Elements are only created on demand •  Classes implementing the Interface Comparable and providing the methods next() und previous(), can be used in Ranges.
  • 12.
    Collections: Lists •  Simplified Notation(extends the Java-Type List) def list = [1, 2] •  Adding and Removing Values list += 3 list = list - [2] •  We can iterate over the elements list.each { n -> println n } •  [1, 2, 3] [1, 3] 1 3 Subscript operator is supported (as with Ranges)
  • 13.
    Collections: Maps •  Simplified Notation( extends the Java-Type Map) def map = [ „name“: „Groovy“, „typ“: „Language“ ] •  Accessing Elements map.each { entry -> println „$entry.key: $entry.value“} map [„name“] = „English“ •  Shortened Access println map.name English name: Groovy typ: Language
  • 14.
    Control Structures •  New ForLoop Syntax for ( i in 1..5 ) println „Hello $i“ Hello 1 Hello 2 Hello 3 Hello 4 Hello 5 •  Every normal Java control structure is supported (including For Loops) •  Boolean decision much more general through the use of Groovy Truth Coercion of Collections, Iterators, Enumerations, Maps, Matchers, Strings, Numbers and Object References to a boolean expression
  • 15.
    Control Structures: SwitchStatement •  Switch much more general than Java (Example with Type, Range and Closure) switch ( val ) { case { it > 3 }: println „$val is larger than 3“; break case 5..9: println „$val is in the Range 5 – 9“; break case Number: println „$val is of Type Number “; break }
  • 16.
    Operator-Overloading(1) •  Impossible in Java •  Widelyused in Groovy •  Provided for many existing Java classes •  Works by implementing the respective Method Example Operator + Operator … •  Method plus() Method minus() Thus your own implementations are straightforward
  • 17.
    Operator Overloading(2) class Complex{ BigDecimal r BigDecimal i def plus (Complex c) { new Complex (r : this.r + c.r, i : this.i + c.i) } } def res = new Complex(r:1, i:-1) + new Complex (r:1, i:1) println "$res.r + $res.i i" 2+0i
  • 18.
    Closures: Higher-Order Functions •  BasicIdea: Methods are Objects –  Known from functional programming –  There we have first-order (and higher-order) functions •  Anonymous inner classes on Steroids •  Usage –  Separation of Concerns •  Separation of Iteration and Logic •  Central Resource Handling –  Functional Programming Approaches
  • 19.
    Closures: Definition (1) •  Wehave met (anonymous) Closures already map.each { entry -> println „$entry.key: $entry.value“} case { it > 3 }: •  println „$val is larger than 3“ General Definition def c = { p1, p2, p3 = 0 -> [ Source of the Closure] } Parameters can accept Default Values If no Parameter is given, then Implicit Parameter it Return Value is the Result of the last statement
  • 20.
    Closures: Example def square= { x -> x * x } 4 println square(2) r = 1..5 r.each { println square(it) } 1 4 9 16 25 def cubed = { x -> x * square (x) } r.each { println cubed(it) } Implicit Parameter it 1 8 27 64 125
  • 21.
    Closures: Functional Programming(1) •  Definition „In mathematics and computer science, currying is the technique of transforming a function that takes multiple arguments (or a tuple of arguments) in such a way that it can be called as a chain of functions, each with a single argument (partial application). It was originated by Moses Schönfinkel and later re-discovered by Haskell Curry. Because of this, some say it would be more correct to name it schönfinkeling. “ – Wikipedia •  Fixes the number of arguments to a function, thereby generating a new function •  Allows the concatenation of functions
  • 22.
    Closures: Functional Programming(2) def mul = { x, y -> x * y } def mul2 = mul.curry(2) def mul5 = mul.curry(5) println mul2(3) println mul5(2) Equals { y -> 2 * y } Equals { y -> 5 * y } 6 10 def komp = { g, f, x -> g( f(x) ) } def mul10 = komp.curry(mul2, mul5) println mul10(5) // Left Shift Operator mul10 = mul2 << mul5 println mul10(5) g°f (x) := g(f(x)) Currying with Closures 50
  • 23.
    Extending existing Classesusing Categories •  •  •  Third-party Classes sometimes need to be extended or changed Categories change behaviour of Objects and Classe at Runtime Adding or Changing Methods class HelloCategory { public static String hello(String i) { return "Hello, $i" } } def testString = "Joachim" use(HelloCategory) { println testString.hello() } Hello, Joachim
  • 24.
    Examples •  XML parsing •  A WebServer •  A Web Browser •  Domain-Specific Languages
  • 25.
    Example XML-Parsing: AnXML-Structure <groovy> <music> <tune> <title>The 59th Street Bridge Song</title> <artist>Simon and Garfunkel</artist> </tune> <tune> <title>Monday Monday</title> <artist>The Mamas and The Papas</artist> </tune> <tune> <title>Goodnight Moon</title> <artist>Shivaree</artist> </tune> <tune> <title>Suddenly</title> <artist>Soraya</artist> </tune> </music> </groovy>
  • 26.
    XML-Parsing: The GroovyScript and the Output Reference to XML-Tree (equivalent to the root element groovy) The Script result = new XmlSlurper().parse(new File(args[0])) result.music.tune.each { elem -> println "$elem.title, $elem.artist" } The Output The 59th Street Bridge Song, Simon and Garfunkel Monday Monday, The Mamas and The Papas Goodnight Moon, Shivaree Suddenly, Soraya GPath Expression
  • 27.
    Example: WebServer (25Lines) def webPath = args[0] def getPattern = /GET (/?[^? ]*)??([^ ]+)?s+HTTP/[.d]+/ def server = new ServerSocket(5926) while(true) { server.accept() { socket -> socket.withStreams { input, output -> def line, resource def reader = input.newReader() while(line = reader.readLine()) { println line def match = line =~ getPattern if(match) resource = match[0][1] } def f = new File ("$webPath/$resource") if(f.directory) f = "$webPath/$resource/index.html" as File if(!f.exists()) f = "$webPath/error.html" as File } output << "HTTP/1.0 200 OKn" //{{9}} output << "Content-Type: text/htmlnn" output << f.asWritable() } }
  • 28.
    Web-Browser import groovy.swing.SwingBuilder import javax.swing.event.HyperlinkEvent urlAction= { swing.pane.page = new URL(it.actionCommand) } hyperlinkAction = { evt -> if(evt.eventType == HyperlinkEvent.EventType.ACTIVATED) tf.text = swing.pane.page = evt.URL } swing = new SwingBuilder() swing.frame(title: 'Mini-Browser', size: [900, 600], windowClosing: { System.exit(0) } ) { borderLayout() panel (constraints: java.awt.BorderLayout.NORTH) { tf = textField(columns: 50, actionPerformed: urlAction) } scrollPane { editorPane(editable: false, id: 'pane', hyperlinkUpdate: hyperlinkAction, constraints: java.awt.BorderLayout.SOUTH, page: new URL("http://www.spiegel.de")) } }.show()
  • 29.
    Example Domain SpecificLanguage •  (Simplified) Language focusing on a specific problem area •  Used by Domain Experts, not necessarily IT-Personnel •  Focuses on the Problem Domain •  Allows a natural and succinct expression of problems in the problem domain •  Two Approaches –  Internal DSL –  External DSL •  Simple examples for a DSL 3.€ + 4.$ + 10.Yen 2.km + 5.mm + 3.yd+ 2.mi
  • 30.
    DistanceDSL: The ClassUnit class Unit { def ratio String name public static final mm = new Unit(ratio : 0, name : "millimeter") public static final cm = new Unit(ratio : 1, name : "centimeter") // equivalent Entries for m, km, yd, mi … static def convertUnit(Distance d, Unit newUnit) { def factor = ratioTable[d.unit.ratio][newUnit.ratio] if(factor) return d.length * factor else return d.length / ratioTable[newUnit.ratio][d.unit.ratio] } static ratioTable = [ // mm, cm, m, km, y, mi [ 1, 0, 0, 0, 0, 0 ], [ 10, 1, 0, 0, 0, 0 ], // äquivalente Einträge für m, km, yd, mi … ] } // mm // cm
  • 31.
    DistanceDSL: The ClassDistance class Distance implements Comparable { BigDecimal length Unit unit Distance plus(Distance operand) { def newLength = this.length + Unit.convertUnit(operand, this.unit) new Distance(length : newLength, unit : this.unit) } Distance minus(Distance operand) { def newLength = this.length - Unit.convertUnit(operand, this.unit) new Distance(length : newLength, unit : this.unit) } int compareTo(other) { if(this.unit == other.unit) return this.length <=> other.length return this.length <=> Unit.convertUnit(other, this.unit) } String toString() { "$length $unit.name" } }
  • 32.
    DistanceDSL: The Category classDistanceCategory { static Distance getMm(Number n) { new Distance(length : n, unit : Unit.mm) } static Distance getMm(Distance d) { new Distance(length : Unit.convertUnit(d, Unit.mm), unit : Unit.mm) } … Equivalent Lines for getCm(), getM(), getKm(), getYd(), getMi() }
  • 33.
    DistanceDSL: Result use(DistanceCategory.class) { def def def def d1 d2 d3 d4 println println println println println println println println } = = = = 1.m 1.yd 1760.yd 100.cm 1.m+ 1.yd 1.yd + 1.mi 1.m - 1.yd d2.m d3.mi d4.m 1000.yd.km 1000.yd < 1.km 1.9144  meter   1761  yard   0.0856  meter   0.9144  meter   1  mile(s)   1  meter   0.9144000  kilometer   true  
  • 34.
    Meta Object Protocol(1) •  Normally an Object has a fixed set of methods and properties (or interface) •  What happens if the Object can decide each time how to interpret a method call or property access? •  Allows sensible reaction to calls that are not known at implementation time
  • 35.
    Meta Object Protocol(2): A Simple Example •  React to a call to a method that is not implemented wird aufgerufen für alle nicht implementierten Methoden class MOPBeispiel { public invokeMethod(String method, Object params) { println "I have been called with $method()" } } bsp = new MOPBeispiel() bsp.helloWorld() I have been called with helloWorld
  • 36.
    Groovy: Is itworth it? Interlude: The mythical Man-Month Book written in the 70‘s, Author Frederick P. Brooks, Jr. Contains basic wisdom of project management that is still not followed In this context interesting •  Use of Higher Abstractions leads to a Growth in Productivity by a Factor, not by a percentage (p. 186) –  Classical Example is Assembler vs. C •  Introduction of new Languages: In the Beginning High Cost, Wins are reaped later (p. 221 •  Learning the Vocabulary – i.e., the frameworks and libraries – is timeconsuming (p. 224) –  Example Java vs. C#
  • 37.
    Groovy: Is itworth it? •  Language provides Higher Abstractions than Java •  Pro: Groovy is fully compatible to Java –  Java Developers can use Groovy at once –  Every Library and Framework is directly available •  Con: Runtime Performance is lower. But –  Call Site Caching allows Speed-Ups –  Java 1.7 provides new VM-Byte-Code that allows this extremely fast –  Difference is small (typically 1.5) –  Groovy provides static compilation that leads to faster code –  Critical parts of the Application can be written in Java •  Groovy is the dynamic language with the lowest cost for introduction and usage
  • 38.
    What didn’t welook into? •  GPath •  Unit-Tests und Mock-Objekte •  Groovy SQL •  Grails, GORM •  GString •  Bean-Unterstützung •  Reguläre Ausdrücke •  Builder-Unterstützung •  Generics •  Annotations •  AST Transformations •  …
  • 39.
    More Information •  Website http://groovy.codehaus.org • The Definitive Book „Groovy in Action“, Dierk König, Manning Publishing http://www.manning.com/koenig •  Lot of additional books in many languages
  • 40.
    Questions? Dr. Joachim Baumann codecentricAG An der Welle 4 60322 Frankfurt joachim.baumann@codecentric.de www.codecentric.de blog.codecentric.de Datum/ Fragen 40