Slide 1

Slide 1 text

Tecnologie Groovy Prima Parte Giugno 2013 Francesco Lerro venerdì 28 giugno 13

Slide 2

Slide 2 text

Obiettivi del talk • Mostrare le peculiarità del linguaggio • Introdurre alcuni tool legati a Groovy • Farvi venire voglia di provarlo :) venerdì 28 giugno 13

Slide 3

Slide 3 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = new ArrayList(); ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs.get(i); ! ! ! if (s.length() <= maxLen){ ! ! ! ! results.add(s); ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = new ArrayList(); ! ! names.add("Giulio"); names.add("Laura"); ! ! names.add("Mario"); names.add("Anna"); ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames.get(i); ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 4

Slide 4 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = new ArrayList(); ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs.get(i); ! ! ! if (s.length() <= maxLen){ ! ! ! ! results.add(s); ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = new ArrayList(); ! ! names.add("Giulio"); names.add("Laura"); ! ! names.add("Mario"); names.add("Anna"); ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames.get(i); ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 5

Slide 5 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = new ArrayList(); ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs.get(i); ! ! ! if (s.length() <= maxLen){ ! ! ! ! results.add(s); ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = new ArrayList(); ! ! names.add("Giulio"); names.add("Laura"); ! ! names.add("Mario"); names.add("Anna"); ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames.get(i); ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 6

Slide 6 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = new ArrayList(); ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs.get(i); ! ! ! if (s.length() <= maxLen){ ! ! ! ! results.add(s); ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = new ArrayList(); ! ! names.add("Giulio"); names.add("Laura"); ! ! names.add("Mario"); names.add("Anna"); ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames.get(i); ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 7

Slide 7 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = new ArrayList(); ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs.get(i); ! ! ! if (s.length() <= maxLen){ ! ! ! ! results.add(s); ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = new ArrayList(); ! ! names.add("Giulio"); names.add("Laura"); ! ! names.add("Mario"); names.add("Anna"); ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames.get(i); ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 8

Slide 8 text

import java.util.List; import java.util.ArrayList; class Filter { ! static List filterLongerThan(List xs, int maxLen) { ! ! List results = [] ! ! for (int i=0; i < xs.size(); i++){ ! ! ! String s = xs[i] ! ! ! if (s.length() <= maxLen){ ! ! ! ! results << s ! ! ! } ! ! } ! ! return results; ! } ! public static void main(String[] args) { ! ! List names = ["Giulio", "Laura", "Mario", "Anna"] ! ! System.out.println(names); ! ! List shortNames = filterLongerThan(names, 5); ! ! System.out.println("After filtering: " + shortNames.size()); ! ! for (int i=0; i < shortNames.size(); i++) { ! ! ! String s = shortNames[i] ! ! ! System.out.println(s); ! ! } ! } } venerdì 28 giugno 13

Slide 9

Slide 9 text

import java.util.List; import java.util.ArrayList; class Filter { static List filterLongerThan(List xs, int maxLen) { List results = [] for (int i=0; i < xs.size(); i++){ String s = xs[i] if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List shortNames = filterLongerThan(names, 5); System.out.println("After filtering: " + shortNames.size()); for (int i=0; i < shortNames.size(); i++) { String s = shortNames[i]; System.out.println(s); } } } venerdì 28 giugno 13

Slide 10

Slide 10 text

import java.util.List; import java.util.ArrayList; class Filter { static List filterLongerThan(List xs, int maxLen) { List results = [] for (int i=0; i < xs.size(); i++){ String s = xs[i] if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List shortNames = filterLongerThan(names, 5); System.out.println("After filtering: " + shortNames.size()); for (int i=0; i < shortNames.size(); i++) { String s = shortNames[i]; System.out.println(s); } } } venerdì 28 giugno 13

Slide 11

Slide 11 text

class Filter { static List filterLongerThan(List xs, int maxLen) { List results = [] xs.each { s -> if (s.length() <= maxLen){ results << s } } return results; } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] println(names); List shortNames = filterLongerThan(names, 5); println("After filtering: " + shortNames.size()); shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 12

Slide 12 text

class Filter { static List filterLongerThan(List xs, int maxLen) { List results = [] results = xs.findAll { s -> s.length() <= maxLen } return results; } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List shortNames = filterLongerThan(names, 5) println("After filtering: " + shortNames.size()) shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 13

Slide 13 text

class Filter { static List filterLongerThan(List xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] println(names); List shortNames = filterLongerThan(names, 5); println("After filtering: " + shortNames.size()); shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 14

Slide 14 text

class Filter { static List filterLongerThan(List xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List shortNames = filterLongerThan(names, 5) println("After filtering: " + shortNames.size()) shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 15

Slide 15 text

class Filter { static List filterLongerThan(List xs, int maxLen) { xs.findAll { s -> s.length() <= maxLen } } public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] println(names) List shortNames = filterLongerThan(names, 5) println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 16

Slide 16 text

class Filter { public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] int maxLen = 5 println(names) List shortNames = names.findAll { s -> s.length() <= maxLen } println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } } } -70% venerdì 28 giugno 13

Slide 17

Slide 17 text

class Filter { public static void main(String[] args) { List names = ["Giulio", "Laura", "Mario", "Anna"] int maxLen = 5 println(names) List shortNames = names.findAll { s -> s.length() <= maxLen } println("After filtering: ${shortNames.size()}") shortNames.each { println(it) } } } venerdì 28 giugno 13

Slide 18

Slide 18 text

+ Smalltalk { venerdì 28 giugno 13

Slide 19

Slide 19 text

+ optionally typed, dinamico, funzionale venerdì 28 giugno 13

Slide 20

Slide 20 text

Opzionalmente tipizzato venerdì 28 giugno 13

Slide 21

Slide 21 text

Dinamico • Aggiunta a compile-time di funzionalità: metodi, propietà, costruttori • Runtime mixins ed invocazione di metodi il cui nome risiede in una variabile venerdì 28 giugno 13

Slide 22

Slide 22 text

Dinamico - ExpandoMetaClass venerdì 28 giugno 13

Slide 23

Slide 23 text

Dinamico - ExpandoMetaClass Aggiunta funzionalità a compile-time anche se final venerdì 28 giugno 13

Slide 24

Slide 24 text

Dinamico - Metodi su collection venerdì 28 giugno 13

Slide 25

Slide 25 text

Dinamico - Mixin di metodi @Category(Vehicle) class FlyingAbility { def fly() { "${name}: fly!" } } @Category(Vehicle) class DivingAbility { def dive() { "${name}: dive!" } } interface Vehicle { String getName() } @Mixin(FlyingAbility) class Plane implements Vehicle { String getName() { "Concorde" } } @Mixin([DivingAbility, FlyingAbility]) class JamesBondVehicle implements Vehicle { String getName() { "James Bond's vehicle" } } assert new Plane().fly() == "Concorde: fly!" assert new JamesBondVehicle().fly() == "James Bond's vehicle: fly!" assert new JamesBondVehicle().dive() == "James Bond's vehicle: dive!" venerdì 28 giugno 13

Slide 26

Slide 26 text

Dinamico - Via annotation • Iniezione funzionalità via annotation • @Immutable (@Canonical) • @Bindable • @Delegate • @Newify • @Lazy • @Log • etc. venerdì 28 giugno 13

Slide 27

Slide 27 text

Dinamico - Esempio @Delegate venerdì 28 giugno 13

Slide 28

Slide 28 text

Funzionale • Funzioni come first class citizens (Closure) • associabili ad una variabile • usate come parametri di altre funzioni • componibili • zucchero sintattico venerdì 28 giugno 13

Slide 29

Slide 29 text

Funzionale - Esempio di currying venerdì 28 giugno 13

Slide 30

Slide 30 text

La Groovy “verità” • Regole per la coercizione in boolean • Collezioni: true se NON vuote • Stringhe: true se NON vuote o nulle • Oggetti: true se NON nulli • Regexp Pattern: true se MATCH venerdì 28 giugno 13

Slide 31

Slide 31 text

Groovy truth - Esempi venerdì 28 giugno 13

Slide 32

Slide 32 text

Groovy truth - Esempi Usa gli operatori ?. e ?: in combinazione per evitare NPE venerdì 28 giugno 13

Slide 33

Slide 33 text

Builder venerdì 28 giugno 13

Slide 34

Slide 34 text

Builder venerdì 28 giugno 13

Slide 35

Slide 35 text

Builder venerdì 28 giugno 13

Slide 36

Slide 36 text

Slurper import java.io.*; import javax.xml.parsers.*; import org.w3c.dom.*; public class XMLReader { public static void main(String argv[]) throws Exception { File file = new File("customers.xml"); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document doc = db.parse(file); doc.getDocumentElement().normalize(); NodeList nodeLst = doc.getElementsByTagName("customer"); for (int s = 0; s < nodeLst.getLength(); s++) { Element item = (Element) nodeLst.item(s); System.out.println(item.getAttribute("name")); } } } venerdì 28 giugno 13

Slide 37

Slide 37 text

Slurper def xmlFile = new File('customers.xml') def xml = new XmlSlurper().parse(xmlFile) xml.customer.each { println it.'@name'.text() } Anche per JSON, Config, ... venerdì 28 giugno 13

Slide 38

Slide 38 text

Performance • Dinamico implica overhead • spesso diversi punti % • Molti miglioramenti da Groovy 2.0 • primitiva invokeDynamic (Java 7) • @CompileStatic • Valutare trade-off produttività VS velocità venerdì 28 giugno 13

Slide 39

Slide 39 text

Performance... @Grab('com.googlecode.gbench:gbench:0.4.2-groovy-2.1') import gbench.BenchmarkBuilder import groovy.transform.CompileStatic int fib(int n) { if (n < 2) return n return fib(n - 1) + fib(n - 2) } @CompileStatic int fib2(int n) { if (n < 2) return n return fib2(n - 1) + fib2(n - 2) } new BenchmarkBuilder().run { int n = 20 "Normal Version" { fib n } "@CompileStatic Version" { fib2 n } }.prettyPrint() venerdì 28 giugno 13

Slide 40

Slide 40 text

Performance... @Grab('com.googlecode.gbench:gbench:0.4.2-groovy-2.1') import gbench.BenchmarkBuilder import groovy.transform.CompileStatic int fib(int n) { if (n < 2) return n return fib(n - 1) + fib(n - 2) } @CompileStatic int fib2(int n) { if (n < 2) return n return fib2(n - 1) + fib2(n - 2) } new BenchmarkBuilder().run { int n = 20 "Normal Version" { fib n } "@CompileStatic Version" { fib2 n } }.prettyPrint() * JVM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04... * JRE: 1.7.0_10 * Total Memory: 81.1875 MB * Maximum Memory: 1123.5625 MB * OS: Mac OS X (10.7.5, x86_64) Options ======= * Warm Up: Auto * CPU Time Measurement: On user system cpu real Normal Version 92622 7 92630 92626 @CompileStatic Version 39974 3 39977 39976 venerdì 28 giugno 13

Slide 41

Slide 41 text

Ecosistema Geb, Spock, WSLite... venerdì 28 giugno 13

Slide 42

Slide 42 text

Ecosistema Geb, Spock, WSLite... Nella seconda parte approfondiremo il discorso su queste tecnologie! venerdì 28 giugno 13

Slide 43

Slide 43 text

Riferimenti • Groovy User Guide - http://groovy.codehaus.org/User+Guide • Bob Brown - The future is Gr8 - http://wordpress.transentia.com.au/wordpress/ 2013/05/07/disaster/ • Sergey Dolgopolov - Testing the performance of new Groovy 2.0 release with GBench - http://www.sergeydolgopolov.me/2012/07/groovy-20-has-been-released- testing-new.html • Guillame Laforge - Groovy Ecosystem - http://www.slideshare.net/glaforge/groovy- ecosystem-jfokus-2011-guillaume-laforge • Hubert Klein Ikkink (aka mrhaki) - Groovy goodness blog - http://mrhaki.blogspot.it/ • Geb Samples - http://www.gebish.org • GPars Samples for Dataflow and Actors - http://gpars.codehaus.org • Spock Samples - http://code.google.com/p/spock/ • Tim Myer - http://timezra.blogspot.it/2011/11/trampoline-and-memoize.html venerdì 28 giugno 13

Slide 44

Slide 44 text

Web: http://rolandfg.net Twitter: @flerro venerdì 28 giugno 13