Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tecnologie Groovy - Prima parte

Tecnologie Groovy - Prima parte

A talk given at JUG Milan (Italy) about Groovy peculiarities and its technology ecosystem. Slides are in Italian, sorry :)

This 'Part one' is focused on how Groovy makes Java more agile and how it brings fun back into programming.

Code samples used throughout the talk are available for download at: https://github.com/flerro/groovy-tech-JUG-talk-06.2013

Francesco Lerro

June 27, 2013
Tweet

More Decks by Francesco Lerro

Other Decks in Programming

Transcript

  1. Obiettivi del talk • Mostrare le peculiarità del linguaggio •

    Introdurre alcuni tool legati a Groovy • Farvi venire voglia di provarlo :) venerdì 28 giugno 13
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. Dinamico - Via annotation • Iniezione funzionalità via annotation •

    @Immutable (@Canonical) • @Bindable • @Delegate • @Newify • @Lazy • @Log • etc. venerdì 28 giugno 13
  20. Funzionale • Funzioni come first class citizens (Closure) • associabili

    ad una variabile • usate come parametri di altre funzioni • componibili • zucchero sintattico venerdì 28 giugno 13
  21. 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
  22. Groovy truth - Esempi Usa gli operatori ?. e ?:

    in combinazione per evitare NPE venerdì 28 giugno 13
  23. 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
  24. 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
  25. 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
  26. 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
  27. 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
  28. 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