groovy: il linguaggio

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

Upload: francesco-lerro

Post on 06-Aug-2015

41 views

Category:

Technology


1 download

TRANSCRIPT

Tecnologie GroovyPrima Parte

Giugno 2013 Francesco Lerro

venerdì 28 giugno 13

Obiettivi del talk

• Mostrare le peculiarità del linguaggio

• Introdurre alcuni tool legati a Groovy

• Farvi venire voglia di provarlo :)

venerdì 28 giugno 13

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! 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<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! 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<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! 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<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! 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<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> results = new ArrayList<String>();! ! 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<String> names = new ArrayList<String>();! ! names.add("Giulio"); names.add("Laura");! ! names.add("Mario"); names.add("Anna");! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter {! static List<String> filterLongerThan(List<String> xs, int maxLen) {! ! List<String> 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<String> names = ["Giulio", "Laura", "Mario", "Anna"]! ! System.out.println(names);! ! List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> 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<String> names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List<String> 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

import java.util.List;import java.util.ArrayList;

class Filter { static List<String> filterLongerThan(List<String> xs, int maxLen) { List<String> 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<String> names = ["Giulio", "Laura", "Mario", "Anna"] System.out.println(names); List<String> 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

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

venerdì 28 giugno 13

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

venerdì 28 giugno 13

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

venerdì 28 giugno 13

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

venerdì 28 giugno 13

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

venerdì 28 giugno 13

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

-70%

venerdì 28 giugno 13

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

venerdì 28 giugno 13

+Smalltalk

{venerdì 28 giugno 13

+optionally typed,

dinamico, funzionale

venerdì 28 giugno 13

Opzionalmente tipizzato

venerdì 28 giugno 13

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

Dinamico - ExpandoMetaClass

venerdì 28 giugno 13

Dinamico - ExpandoMetaClass

Aggiunta funzionalità a

compile-time anche se final

venerdì 28 giugno 13

Dinamico - Metodi su collection

venerdì 28 giugno 13

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

Dinamico - Via annotation• Iniezione funzionalità via annotation

• @Immutable (@Canonical)

• @Bindable

• @Delegate

• @Newify

• @Lazy

• @Log

• etc.

venerdì 28 giugno 13

Dinamico - Esempio @Delegate

venerdì 28 giugno 13

Funzionale

• Funzioni come first class citizens (Closure)

• associabili ad una variabile

• usate come parametri di altre funzioni

• componibili

• zucchero sintattico

venerdì 28 giugno 13

Funzionale - Esempio di currying

venerdì 28 giugno 13

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

Groovy truth - Esempi

venerdì 28 giugno 13

Groovy truth - Esempi

Usa gli operatori ?. e ?: in

combinazione per evitare NPE

venerdì 28 giugno 13

Builder

venerdì 28 giugno 13

Builder

venerdì 28 giugno 13

Builder

venerdì 28 giugno 13

Slurper<?xml version="1.0" ?><customers> <customer name="Mario Rossi" /> <customer name="Giovanni Bianchi" /></customers>

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

Slurper<?xml version="1.0" ?><customers> <customer name="Mario Rossi" /> <customer name="Giovanni Bianchi" /></customers>

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

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

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

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

Ecosistema

Geb, Spock, WSLite...

venerdì 28 giugno 13

Ecosistema

Geb, Spock, WSLite...

Nella seconda parte

approfondiremo il discorso

su queste tecnologie!

venerdì 28 giugno 13

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

Web: http://rolandfg.net Twitter: @flerro

venerdì 28 giugno 13