Le téléchargement de votre SlideShare est en cours. ×
0
What’s new inGroovy 2.0  Guillaume Laforge  Groovy Project Manager  SpringSource / VMware       @glaforge                 ...
Guillaume Laforge •   Groovy Project Manager at VMware     •Initiator of the Grails framework     •Creator of the Gaelyk •...
Agenda (1/2) • What’s in Groovy 1.8?  • Nicer DSLs with command chains  • Runtime performance improvements  • GPars bundle...
Agenda (2/2) • What’s new in Groovy 2.0?  • Alignments with JDK 7   • Project Coin (small language changes)   • Invoke Dyn...
Command chains •   A grammar improvement allowing you     to drop dots & parens     when chaining method calls     • an ex...
Command chains     pull request on github                              6
Command chains      Alternation of      method names     pull request on github                              6
Command chains      Alternation of      method names     pull request on github                   and parameters          ...
Command chains     pull request on github                              6
Command chains      Equivalent to:     pull request on github       (     ). (  )                              6
Command chains                 7
Command chains   // methods with multiple arguments (commas)                                                 7
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor                  ...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor   // leverage nam...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor      (   ). (    ...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor      (   ). (    ...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor      (   ). (    ...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor      (   ). (    ...
Command chains   // methods with multiple arguments (commas)   take coffee  with sugar, milk  and liquor      (   ). (    ...
GPars bundled •   GPars is bundled in the Groovy distribution •   GPars covers a wide range of parallel     and concurrent...
Closure enhancements • Closure annotation parameters •    Some more functional flavor     • composition         •         c...
Closure annotation     @Retention(RetentionPolicy.RUNTIME)     @interface Invariant {            Class value() // a closur...
Closure annotation     @Retention(RetentionPolicy.RUNTIME)     @interface Invariant {            Class value() // a closur...
Closure memoization                      11
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()                                                   ...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms           ...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert   plus(1,   2)   ==   3   //   after 1000m...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert   plus(1,   2)   ==   3   //   after 1000m...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 //    after 1000ms  assert...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Closure memoization  def plus = { a, b -> sleep 1000; a + b }.memoize()  assert plus(1, 2) == 3 // after 1000ms  assert pl...
Builtin JSON support •   Consuming •   Producing •   Pretty-printing                       12
Builtin JSON support  import groovy.json.*   def payload = new URL(    "http://github.../json/commits/...").text   def slu...
Builtin JSON supportimport groovy.json.*  def json = new JsonBuilder()  json.person {       name "Guillaume"   age 35     ...
Builtin JSON supportimport groovy.json.*  def json = new JsonBuilder()  json.person {                 {       name "Guilla...
Builtin JSON support  import groovy.json.*      println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":35...
New AST transformations•       @Log                  •       Controlling execution                                  •    @...
@Log•   Four different loggers can be injected    •@Log    •@Commons                   import groovy.util.logging.*     •@...
@Log•   Four different loggers can be injected    •@Log    •@Commons                   import groovy.util.logging.*     •@...
Controlling code execution •   Your application may run user’s code     •what if the code runs in infinite loops or for too...
@ThreadInterrupt   @ThreadInterrupt   import groovy.transform.ThreadInterrupt        while (true) {       // eat lots of C...
@ThreadInterrupt      @ThreadInterrupt      import groovy.transform.ThreadInterrupt              while (true) {  {     if ...
@ToString•       Provides a default toString() method to your types•       Available annotation options    •    includeNam...
@EqualsAndHashCode•   Provides default implementations for equals() and    hashCode() methods            import groovy.tra...
@TupleConstructor•   Provides a « classical » constructor with all properties•   Several annotation parameter options avai...
@InheritConstructors•   Classes like Exception are painful when extended,    as all the base constructors should be replic...
@InheritConstructors•   Classes like Exception are painful when extended,    as all the base constructors should be replic...
Miscellaneous •   Compilation customizers •   Java 7 diamond operator •   Slashy and dollar slashy strings •   New GDK met...
What’sin storefor 2.0?
Groovy 2.0 •   A more modular Groovy •   Java 7 alignements: Project Coin     • binary literals     • underscore in litera...
Groovy Modularity •   Groovy’s « all » JAR weighs in at 6 MB • Nobody needs everything  • Template engine, Ant scripting, ...
The new JARs •   A smaller groovy.jar: 3MB •   Modules     •console                    •   sql     •docgenerator          ...
Extension modules •   Create your own module     •contribute instance extension methods package foo class StringExtension ...
Extension modules •   Create your own module     •contribute instance extension methods    Same structure                 ...
Extension modules •   Create your own module     •contribute class extension methods              package foo             ...
Extension module descriptor •   Descriptor in: META-INF/services/     org.codehaus.groovy.runtime.ExtensionModule moduleNa...
Java 7 / JDK 7 •   Project Coin and InvokeDynamic                                      32
Binary literals•   We had decimal, octal and hexadecimal notations for    number literals•   We can now use binary represe...
Underscore in literals•   Now we can also add underscores    in number literals for more readability    long creditCardNum...
Multicatch•   One block for multiple exception caught    •rather than duplicating the block        try {           /* ... ...
InvokeDynamic • Groovy 2.0 supports JDK 7’s invokeDynamic  • compiler has a flag for compiling against JDK 7  • might use t...
Static Type Checking •   Goal: make the Groovy compiler «grumpy»!     •   and throw compilation errors (not at runtime) • ...
Typos in a variable or import groovy.transform.TypeChecked   void method() {}   @TypeChecked test() {   // Cannot find matc...
Typos in a variable or import groovy.transform.TypeChecked   void method() {}   @TypeChecked test() {   // Cannot find matc...
Typos in a variable or                                        Annotation can be at                                        ...
Wrong assignments    // cannot assign value of type... to variable...    int x = new Object()    Set set = new Object()   ...
Wrong assignments    // cannot assign value of type... to variable...    int x = new Object()    Set set = new Object()   ...
Wrong return types    // checks if/else branch return values    @TypeChecked    int method() {       if (true) { String } ...
Wrong return types    // checks if/else branch return values    @TypeChecked    int method() {                      Compil...
Type inference    @TypeChecked test() {      def name = "  Guillaume  "           // String type infered (even inside GStr...
Statically checked & dyn.     @TypeChecked     String greeting(String name) {        // call method with dynamic behavior ...
Instanceof checks   @TypeChecked   void test(Object val) {       if (val instanceof String) {           println val.toUppe...
Instanceof checks                                             No need   @TypeChecked                              for cast...
Instanceof checks                                             No need   @TypeChecked                              for cast...
Lowest Upper Bound •   Represents the lowest « super » type classes     have in common     •may be virtual (aka « non-deno...
Lowest Upper Bound •   Represents the lowest « super » type classes     have in common     •may be virtual (aka « non-deno...
Lowest Upper Bound •   Represents the lowest « super » type classes     have in common     •may be virtual (aka « non-deno...
Flow typing •       Static type checking shouldn’t complain even for bad coding         practicies which work without type...
Gotcha: static checking vs •   Type checking works at compile-time     •adding @TypeChecked doesn’t change behavior       ...
Gotcha: runtime     @TypeChecked     void test() {       Integer.metaClass.foo = {}       123.foo()     }                 ...
Gotcha: runtime     @TypeChecked     void test() {       Integer.metaClass.foo = {}       123.foo()     }                 ...
Gotcha: runtime     @TypeChecked     void test() {       Integer.metaClass.foo = {}       123.foo()     }       Method not...
Gotcha: explicit type for @TypeChecked test() {   ["a", "b", "c"].collect {      it.toUpperCase() // Not OK   } } •   A « ...
Gotcha: explicit type for @TypeChecked test() {   ["a", "b", "c"].collect { String it ->      it.toUpperCase() // OK, it’s...
Closure shared variables      @TypeChecked test() {        def var = "abc"        def cl = { var = new Date() }        cl(...
Closure shared variables                          var assigned in the closure:                           «shared closure v...
Closure shared variables                                     var assigned in the closure:                                 ...
Closure shared variables                                          var assigned in the closure:                            ...
Closure shared variables     class A       { void foo() {} }     class B extends A { void bar() {} }     @TypeChecked test...
Closure shared variables     class A       { void foo() {} }     class B extends A { void bar() {} }     @TypeChecked test...
Static Compilation •   Given your Groovy code can be type checked...     we can as well compile it « statically »     •   ...
Static Compilation: •   You gain:     •Type safety      • thanks to static type checking          •          static compil...
Static Compilation: •   But you loose:     •   Dynamic features         •metaclass changes, categories, etc.     •   Dynam...
Statically compiled & dyn.     @CompileStatic     String greeting(String name) {        // call method with dynamic behavi...
What about performance? •   Comparisons between:     •   Java     •   Groovy static compilation (Groovy 2.0)     •   Groov...
What about performance?                                            Pi (π)     Binary                              Fibonacc...
Summary •   Main themes of the Groovy 2.0 release     •Modularity     •   Embark the JDK 7 enhancements         •Project C...
Thank you!                           ge                    e Lafor lopment       Gu illaum ovy Deve                 Gro   ...
Questions & Answers •   Got questions, really?                              Q&A                                    59
Image credits •   Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg •   Pills: http://www.we-ew.com/wp-c...
Prochain SlideShare
Chargement dans... 5
×

JavaOne 2012 Groovy update

1,752

Published on

Groovy update presentation at JavaOne 2012

Published in: Technologies
0 commentaires
13 mentions J'aime
Statistiques
Remarques
  • Soyez le premier à commenter

Aucun téléchargement
Vues
Total des vues
1,752
Sur Slideshare
0
À partir des ajouts
0
Nombre d'ajouts
2
Actions
Partages
0
Téléchargements
49
Commentaires
0
J'aime
13
Ajouts 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript of "JavaOne 2012 Groovy update"

    1. 1. What’s new inGroovy 2.0 Guillaume Laforge Groovy Project Manager SpringSource / VMware @glaforge 1
    2. 2. Guillaume Laforge • Groovy Project Manager at VMware •Initiator of the Grails framework •Creator of the Gaelyk • Co-author of Groovy in Action • Follow me on... •My blog: http://glaforge.appspot.com •Twitter: @glaforge •Google+: http://gplus.to/glaforge 2
    3. 3. Agenda (1/2) • What’s in Groovy 1.8? • Nicer DSLs with command chains • Runtime performance improvements • GPars bundled for taming your multicores • Closure enhancements • Builtin JSON support • New AST transformations 3
    4. 4. Agenda (2/2) • What’s new in Groovy 2.0? • Alignments with JDK 7 • Project Coin (small language changes) • Invoke Dynamic support • Continued runtime performance improvements • Static type checking • Static compilation • Modularity 4
    5. 5. Command chains • A grammar improvement allowing you to drop dots & parens when chaining method calls • an extended version of top-level statements like println • Less dots, less parens allow you to •write more readable business rules •in almost plain English sentences • (or any language, of course) 5
    6. 6. Command chains pull request on github 6
    7. 7. Command chains Alternation of method names pull request on github 6
    8. 8. Command chains Alternation of method names pull request on github and parameters (even named ones) 6
    9. 9. Command chains pull request on github 6
    10. 10. Command chains Equivalent to: pull request on github ( ). ( ) 6
    11. 11. Command chains 7
    12. 12. Command chains // methods with multiple arguments (commas) 7
    13. 13. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor 7
    14. 14. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation 7
    15. 15. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good 7
    16. 16. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures 7
    17. 17. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} 7
    18. 18. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens 7
    19. 19. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names 7
    20. 20. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms 7
    21. 21. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 7
    22. 22. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 7
    23. 23. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 7
    24. 24. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 7
    25. 25. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names ( ). . ( ) // possible with an odd number of terms take 3  cookies 7
    26. 26. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names ( ). . ( ) // possible with an odd number of terms take). cookies ( 3  7
    27. 27. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms •actors, fork/join, map/filter/reduce, dataflow, agents •parallel arrays, executors, STM, and more... • And you can use it from plain Java as well! • http://gpars.codehaus.org/ 8
    28. 28. Closure enhancements • Closure annotation parameters • Some more functional flavor • composition • compose several closures into one single closure • trampoline • avoid stack overflow errors for recursive algorithms • memoization • remember the outcome of previous closure invocations • currying improvements 9
    29. 29. Closure annotation @Retention(RetentionPolicy.RUNTIME) @interface Invariant {     Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {     float number     String unit }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) 10
    30. 30. Closure annotation @Retention(RetentionPolicy.RUNTIME) @interface Invariant {     Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {     float number     Poor-m an’s GCont racts String unit }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) 10
    31. 31. Closure memoization 11
    32. 32. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() 11
    33. 33. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms 11
    34. 34. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately 11
    35. 35. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms 11
    36. 36. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately   11
    37. 37. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     11
    38. 38. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached 11
    39. 39. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10) 11
    40. 40. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   11
    41. 41. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached 11
    42. 42. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  11
    43. 43. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  // between 10 and 20 invocations cached 11
    44. 44. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately     // at least 10 invocations cached def plusAtLeast = { ... }.memoizeAtLeast(10)   // at most 10 invocations cached def plusAtMost = { ... }.memoizeAtMost(10)  // between 10 and 20 invocations cached def plusAtLeast = { ... }.memoizeBetween(10, 20) 11
    45. 45. Builtin JSON support • Consuming • Producing • Pretty-printing 12
    46. 46. Builtin JSON support import groovy.json.*  def payload = new URL( "http://github.../json/commits/...").text  def slurper = new JsonSlurper() def doc = slurper.parseText(payload)  doc.commits.message.each { println it } 13
    47. 47. Builtin JSON supportimport groovy.json.*  def json = new JsonBuilder()  json.person {     name "Guillaume" age 35     pets "Hector", "Felix"} println json.toString() 14
    48. 48. Builtin JSON supportimport groovy.json.*  def json = new JsonBuilder()  json.person {     {     name "Guillaume" "person": {         "name": "Guillaume",         age 35     "age": 35,         pets "Hector", "Felix" "pets": [            }  "Hector",            println json.toString() "Felix"         ]     } } 14
    49. 49. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint( {"person":{"name":"Guillaume","age":35, + "pets":["Hector","Felix"]}}) {     "person": {         "name": "Guillaume",         "age": 35,         "pets": [             "Hector",             "Felix"         ]     } } 15
    50. 50. New AST transformations• @Log • Controlling execution • @ThreadInterrupt• @Field • @TimedInterrupt • @ConditionalInterrupt• @AutoClone • @InheritConstructor• @AutoExternalizable • @WithReadLock• @Canonical • @WithWriteLock • @ToString • @EqualsAndHashCode • @TupleConstructor • @ListenerList 16
    51. 51. @Log• Four different loggers can be injected •@Log •@Commons import groovy.util.logging.*  •@Log4j   @Log •@Slf4j class Car {     Car() {         log.info Car constructed    • Possible to implement }  } your own strategy   def c = new Car() 17
    52. 52. @Log• Four different loggers can be injected •@Log •@Commons import groovy.util.logging.*  •@Log4j   @Log •@Slf4j Guarded w/ an if class Car {     Car() {         log.info Car constructed    • Possible to implement }  } your own strategy   def c = new Car() 17
    53. 53. Controlling code execution • Your application may run user’s code •what if the code runs in infinite loops or for too long? •what if the code consumes too many resources? • 3 new transforms at your rescue •@ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted •@TimedInterrupt: adds checks in method and closure bodies to verify it’s run longer than expected •@ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code 18
    54. 54. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { // eat lots of CPU } 19
    55. 55. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { { if (Thread.currentThread().isInterrupted()) throw new InterruptedException() // eat lots of CPU } 19
    56. 56. @ToString• Provides a default toString() method to your types• Available annotation options • includeNames, includeFields, includeSuper, excludes import groovy.transform.ToString    @ToString class Person {     String name     int age }    println new Person(name: Pete, age: 15) // => Person(Pete, 15) 20
    57. 57. @EqualsAndHashCode• Provides default implementations for equals() and hashCode() methods import groovy.transform.EqualsAndHashCode    @EqualsAndHashCode class Coord {     int x, y }    def c1 = new Coord(x: 20, y: 5) def c2 = new Coord(x: 20, y: 5)    assert c1 == c2 assert c1.hashCode() == c2.hashCode() 21
    58. 58. @TupleConstructor• Provides a « classical » constructor with all properties• Several annotation parameter options available import groovy.transform.TupleConstructor    @TupleConstructor class Person {     String name     int age }    def m = new Person(Marion, 4)         assert m.name == Marion assert m.age == 4 22
    59. 59. @InheritConstructors• Classes like Exception are painful when extended, as all the base constructors should be replicated class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) } } 23
    60. 60. @InheritConstructors• Classes like Exception are painful when extended, as all the base constructors should be replicated import groovy.transform.* @InheritConstructors class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) } } 23
    61. 61. Miscellaneous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion • Customizing the Groovysh prompt • Executing remote scripts 24
    62. 62. What’sin storefor 2.0?
    63. 63. Groovy 2.0 • A more modular Groovy • Java 7 alignements: Project Coin • binary literals • underscore in literals • multicatch • JDK 7: InvokeDynamic • Static type checking • Static compilation 26
    64. 64. Groovy Modularity • Groovy’s « all » JAR weighs in at 6 MB • Nobody needs everything • Template engine, Ant scripting, Swing UI building... • Provide a smaller core •and several smaller JARs per feature • Provide hooks for setting up DGM methods, etc. 27
    65. 65. The new JARs • A smaller groovy.jar: 3MB • Modules •console • sql •docgenerator • swing •groovydoc • servlet •groovysh • templates •ant • test •bsf • testng •jsr-223 • json •jmx • xml 28
    66. 66. Extension modules • Create your own module •contribute instance extension methods package foo class StringExtension { static introduces(String self, String name) { "Hi ${name), I’m ${self}" } } // usage: "Guillaume".introduces("Cédric") 29
    67. 67. Extension modules • Create your own module •contribute instance extension methods Same structure as Categories package foo class StringExtension { static introduces(String self, String name) { "Hi ${name), I’m ${self}" } } // usage: "Guillaume".introduces("Cédric") 29
    68. 68. Extension modules • Create your own module •contribute class extension methods package foo class StaticStringExtension { static hi(String self) { "Hi!" } } // usage: String.hi() 30
    69. 69. Extension module descriptor • Descriptor in: META-INF/services/ org.codehaus.groovy.runtime.ExtensionModule moduleName = stringExtensions moduleVersion = 1.0 // comma-separated list of classes extensionClasses = foo.StringExtension // comma-separated list of classes staticExtensionClasses = foo.StaticStringExtension 31
    70. 70. Java 7 / JDK 7 • Project Coin and InvokeDynamic 32
    71. 71. Binary literals• We had decimal, octal and hexadecimal notations for number literals• We can now use binary representations too int x = 0b10101111 assert x == 175   byte aByte = 0b00100001 assert aByte == 33   int anInt = 0b1010000101000101 assert anInt == 41285 33
    72. 72. Underscore in literals• Now we can also add underscores in number literals for more readability long creditCardNumber = 1234_5678_9012_3456L long socialSecurityNumbers = 999_99_9999L float monetaryAmount = 12_345_132.12 long hexBytes = 0xFF_EC_DE_5E long hexWords = 0xFFEC_DE5E long maxLong = 0x7fff_ffff_ffff_ffffL long alsoMaxLong = 9_223_372_036_854_775_807L long bytes = 0b11010010_01101001_10010100_10010010 34
    73. 73. Multicatch• One block for multiple exception caught •rather than duplicating the block try { /* ... */ } catch(IOException | NullPointerException e) { /* one block to treat 2 exceptions */ } 35
    74. 74. InvokeDynamic • Groovy 2.0 supports JDK 7’s invokeDynamic • compiler has a flag for compiling against JDK 7 • might use the invokeDynamic backport for < JDK 7 • Benefits • more runtime performance! • at least as fast as current « dynamic » Groovy •in the long run, will allow us to get rid of code! • call site caching, thanks to MethodHandles • metaclass registry, thanks to ClassValues • will let the JIT inline calls more easily 36
    75. 75. Static Type Checking • Goal: make the Groovy compiler «grumpy»! • and throw compilation errors (not at runtime) • Not everybody needs dynamic features all the time • think Java libraries scripting • Grumpy should... • tell you about your method or variable typos • complain if you call methods that don’t exist • shout on assignments of wrong types • infer the types of your variables • figure out GDK methods • etc... 37
    76. 76. Typos in a variable or import groovy.transform.TypeChecked   void method() {}   @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood()   def name = "Guillaume" // variable naamme is undeclared println naamme } 38
    77. 77. Typos in a variable or import groovy.transform.TypeChecked   void method() {}   @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood()   def name = "Guillaume" Compilation // variable naamme is undeclared errors! println naamme } 38
    78. 78. Typos in a variable or Annotation can be at class or method level import groovy.transform.TypeChecked   void method() {}   @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood()   def name = "Guillaume" Compilation // variable naamme is undeclared errors! println naamme } 38
    79. 79. Wrong assignments // cannot assign value of type... to variable... int x = new Object() Set set = new Object()   def o = new Object() int x = o   String[] strings = [a,b,c] int str = strings[0]   // cannot find matching method plus() int i = 0 i += 1 39
    80. 80. Wrong assignments // cannot assign value of type... to variable... int x = new Object() Set set = new Object() Compilation   errors! def o = new Object() int x = o   String[] strings = [a,b,c] int str = strings[0]   // cannot find matching method plus() int i = 0 i += 1 39
    81. 81. Wrong return types // checks if/else branch return values @TypeChecked int method() { if (true) { String } else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied @TypeChecked String greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name } 40
    82. 82. Wrong return types // checks if/else branch return values @TypeChecked int method() { Compilation if (true) { String } error! else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied @TypeChecked String greeting(String name) { def sb = new StringBuilder() sb << "Hi " << name } 40
    83. 83. Type inference @TypeChecked test() { def name = "  Guillaume  "   // String type infered (even inside GString) println "NAME = ${name.toUpperCase()}"   // Groovy GDK method support // (GDK operator overloading too) println name.trim()   int[] numbers = [1, 2, 3] // Element n is an int for (int n in numbers) { println n } } 41
    84. 84. Statically checked & dyn. @TypeChecked String greeting(String name) { // call method with dynamic behavior // but with proper signature generateMarkup(name.toUpperCase()) }   // usual dynamic behavior String generateMarkup(String name) { def sw = new StringWriter() new MarkupBuilder(sw).html { body { div name } } sw.toString() } 42
    85. 85. Instanceof checks @TypeChecked void test(Object val) { if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() } } 43
    86. 86. Instanceof checks No need @TypeChecked for casts void test(Object val) { if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() } } 43
    87. 87. Instanceof checks No need @TypeChecked for casts void test(Object val) { if (val instanceof String) { println val.toUpperCase() } else if (val instanceof Number) { println "X" * val.intValue() } } Can call String#multiply(int) from the Groovy Development Kit 43
    88. 88. Lowest Upper Bound • Represents the lowest « super » type classes have in common •may be virtual (aka « non-denotable ») @TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14] } 44
    89. 89. Lowest Upper Bound • Represents the lowest « super » type classes have in common •may be virtual (aka « non-denotable ») @TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14] } Inferred return type: List<Number & Comparable> 44
    90. 90. Lowest Upper Bound • Represents the lowest « super » type classes have in common •may be virtual (aka « non-denotable ») @TypeChecked test() { // an integer and a BigDecimal return [1234, 3.14] } Inferred return type: List<Number & Comparable> 44
    91. 91. Flow typing • Static type checking shouldn’t complain even for bad coding practicies which work without type checks @TypeChecked test() { def var = 123 // inferred type is int int x = var // var is an int var = "123" // assign var with a String x = var.toInteger() // no problem, no need to cast var = 123 x = var.toUpperCase() // error, var is int! } 45
    92. 92. Gotcha: static checking vs • Type checking works at compile-time •adding @TypeChecked doesn’t change behavior • do not confuse with static compilation • Most dynamic features cannot be type checked •metaclass changes, categories •dynamically bound variables (ex: script’s binding) • However, compile-time metaprogramming works •as long as proper type information is defined 46
    93. 93. Gotcha: runtime @TypeChecked void test() { Integer.metaClass.foo = {} 123.foo() } 47
    94. 94. Gotcha: runtime @TypeChecked void test() { Integer.metaClass.foo = {} 123.foo() } Not allowed: metaClass property is dynamic 47
    95. 95. Gotcha: runtime @TypeChecked void test() { Integer.metaClass.foo = {} 123.foo() } Method not Not allowed: recognized metaClass property is dynamic 47
    96. 96. Gotcha: explicit type for @TypeChecked test() { ["a", "b", "c"].collect { it.toUpperCase() // Not OK } } • A « Groovy Enhancement Proposal » to address the issue 48
    97. 97. Gotcha: explicit type for @TypeChecked test() { ["a", "b", "c"].collect { String it -> it.toUpperCase() // OK, it’s a String } } • A « Groovy Enhancement Proposal » to address the issue 48
    98. 98. Closure shared variables @TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK! } 49
    99. 99. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked test() { def var = "abc" def cl = { var = new Date() } cl() var.toUpperCase() // Not OK! } 49
    100. 100. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked test() { Impossible to ensure the def var = "abc" assignment def cl = { var = new Date() }really happens cl() var.toUpperCase() // Not OK! } 49
    101. 101. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked test() { Impossible to ensure the def var = "abc" assignment def cl = { var = new Date() }really happens cl() var.toUpperCase() // Not OK! } Only methods of the most specific compatible type (LUB) are allowed by the type checker 49
    102. 102. Closure shared variables class A { void foo() {} } class B extends A { void bar() {} } @TypeChecked test() { def var = new A() def cl = { var = new B() } cl() var.foo() // OK! } 50
    103. 103. Closure shared variables class A { void foo() {} } class B extends A { void bar() {} } @TypeChecked test() { def var = new A() def cl = { var = new B() } cl() var.foo() // OK! } var is at least an instance of A 50
    104. 104. Static Compilation • Given your Groovy code can be type checked... we can as well compile it « statically » • ie. generate the same byte code as javac • Also interesting for those stuck in JDK < 7 to benefit from performance improvements 51
    105. 105. Static Compilation: • You gain: •Type safety • thanks to static type checking • static compilation builds upon static type checking •Faster code • as close as possible to Java’s performance •Code immune to « monkey patching » • metaprogramming badly used can interfere with framework code •Smaller bytecode size 52
    106. 106. Static Compilation: • But you loose: • Dynamic features •metaclass changes, categories, etc. • Dynamic method dispatch •although as close as possible to « dynamic » Groovy 53
    107. 107. Statically compiled & dyn. @CompileStatic String greeting(String name) { // call method with dynamic behavior // but with proper signature generateMarkup(name.toUpperCase()) }   // usual dynamic behavior String generateMarkup(String name) { def sw = new StringWriter() new MarkupBuilder(sw).html { body { div name } } sw.toString() } 54
    108. 108. What about performance? • Comparisons between: • Java • Groovy static compilation (Groovy 2.0) • Groovy with primitive optimizations (Groovy 1.8+) • Groovy without optimizations (Groovy 1.7) 55
    109. 109. What about performance? Pi (π) Binary Fibonacci quadrature trees Java 191 ms 97 ms 3.6 s Static1.7 1.8 2.0 compilation 197 ms 101 ms 4.3 s Primitive optimizations 360 ms 111 ms 23.7 s No prim. optimizations 2590 ms 3220 ms 50.0 s 56
    110. 110. Summary • Main themes of the Groovy 2.0 release •Modularity • Embark the JDK 7 enhancements •Project Coin •Invoke Dynamic • Static aspects • Static type checking • Static compilation 57
    111. 111. Thank you! ge e Lafor lopment Gu illaum ovy Deve Gro H ead of om ge@ gmail.c Emai l: glafor forge e :@ gla .to/glaforg Twitter : http://gplus spot.com + pp Google p://glaforge.a tt Blog: h 58
    112. 112. Questions & Answers • Got questions, really? Q&A 59
    113. 113. Image credits • Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg • Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg • Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg • Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg • Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg • Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg • Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg • Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg • Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg • Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg • Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg • Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg 60
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×