Groovy Update                         What’s new in Groovy 1.8                         and what’s coming next!            ...
Guillaume Laforge      • Groovy Project Manager      • JSR-241 Spec Lead      • Head of Groovy Development        at Sprin...
Guillaume Laforge      • Groovy Project Manager      • JSR-241 Spec Lead      • Head of Groovy Development        at Sprin...
Groovy 1.7                       3mercredi 18 mai 2011
Groovy 1.7    185                       3mercredi 18 mai 2011
Groovy 1.7    185k                       3mercredi 18 mai 2011
Groovy 1.7    185k               FIRST MONTH                       AFTER RELEASE                                       3me...
Groovy 1.7                       k                           3mercredi 18 mai 2011
Groovy 1.7    177k               SECOND MONTH                       AFTER RELEASE                                       3m...
Groovy 1.7                       k                           3mercredi 18 mai 2011
Groovy 1.7    362k     USERS?                       3mercredi 18 mai 2011
?                       TIP OF                       THEmercredi 18 mai 2011                       ICEBERG
Agenda      •What’s new in Groovy 1.8?            – Nicer DSLs with command chains expressions            – Runtime perfor...
Agenda      •What’s new in Groovy 1.8?            – Nicer DSLs with command chains expressions            – Runtime perfor...
Command chains expressions                                   6mercredi 18 mai 2011
Command chains expressions      • A grammar improvement allowing you to        drop dots & parens when chaining method cal...
Command chains expressions      • A grammar improvement allowing you to        drop dots & parens when chaining method cal...
Command chains expressions      • A grammar improvement allowing you to        drop dots & parens when chaining method cal...
Command chains expressions      • A grammar improvement allowing you to        drop dots & parens when chaining method cal...
Command chains expressions      • A grammar improvement allowing you to        drop dots & parens when chaining method cal...
Command chains expressions                        turn left  then right                                                  7...
Command chains expressions                       Alternation of                       method names                        ...
Command chains expressions                       Alternation of                       method names                        ...
Command chains expressions                        turn left  then right                                                  7...
Command chains expressions                       Equivalent to:                             (    ).    (     )            ...
LookM  a!                       N op are ns,                       no do ts!mercredi 18 mai 2011
Command chains expressions               Before... we used to do...            take 2.pills, of: chloroquinine, after: 6.h...
Command chains expressions               Before... we used to do...            take 2.pills, of: chloroquinine, after: 6.h...
Command chains expressions               Before... we used to do...            take 2.pills, of: chloroquinine, after: 6.h...
Command chains expressions               Before... we used to do...            take 2.pills, of: chloroquinine, after: 6.h...
Command chains expressions               Now, even less punctuation!            take 2.pills  of  chloroquinine  after  6....
Command chains expressions               Now, even less punctuation!                (       ).   (             ).      (  ...
Command chains expressions                       // environment initialization                       Integer.metaClass.get...
Command chains expressions            take 2.pills  of  chloroquinine  after  6.hours                                     ...
Command chains expressions            take 2.pills  of  chloroquinine  after  6.hours                         ... some dot...
Command chains expressions              We could cheat a bit...            take 2  pills of  chloroquinine 6  hours after ...
Command chains expressions              We could cheat a bit...                ( ).     (  ).             ( ).     (     )...
Cheating                       is playing                          with the                        languagemercredi 18 mai...
Command chains expressions              Still doable without cheating though            take 2  pills of  chloroquinine af...
Command chains expressions              Still doable without cheating though                ( ).     (  ).             (  ...
Command chains expressions                       // variable injection                       def (of, after, hours) = /*.....
Command chains expressions                                   17mercredi 18 mai 2011
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Command chains expressions            // methods with multiple arguments (commas)            take coffee  with sugar, milk...
Runtime perf. improvements      • Significant runtime improvements        for primitive int operations            – classi...
GPars bundled      • GPars is bundled in the Groovy distribution      • GPars covers a wide range of parallel and        c...
Closure enhancements      • Closure annotation parameters      • Some more functional flavor            – composition     ...
Closure annotation parameters                  @Retention(RetentionPolicy.RUNTIME)                  @interface Invariant {...
Closure annotation parameters                  @Retention(RetentionPolicy.RUNTIME)                  @interface Invariant {...
Closure composition                 def plus2  = { it + 2 }                 def times3 = { it * 3 }                       ...
Closure trampoline                           23mercredi 18 mai 2011
Closure trampoline         def factorial         factorial = { int n, BigInteger accu = 1G ‐>                             ...
Closure memoization                            24mercredi 18 mai 2011
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 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Closure memoization            def plus = { a, b ‐> sleep 1000; a + b }.memoize()            assert plus(1, 2) == 3 // aft...
Currying improvements                              25mercredi 18 mai 2011
Currying improvements               // right currying               def divide = { a, b ‐> a / b }               def halve...
Currying improvements               // right currying               def divide = { a, b ‐> a / b }               def halve...
Builtin JSON support      • Consuming      • Producing      • Pretty-printing                             26mercredi 18 ma...
Builtin JSON support         import groovy.json.*          def payload = new URL(             "http://github.../json/commi...
Builtin JSON support                       import groovy.json.*                                                def json = ...
Builtin JSON support              import groovy.json.*                              println JsonOutput.prettyPrint(       ...
Builtin JSON support              import groovy.json.*                              println JsonOutput.prettyPrint(       ...
New AST transformations      • @Log                          • @Canonical                                        – @ToStri...
@Log      • Four different loggers can be injected            – @Log, @Commons, @Log4j, @Slf4j      • Possible to implemen...
@Log      • Four different loggers can be injected            – @Log, @Commons, @Log4j, @Slf4j      • Possible to implemen...
@Log      • Four different loggers can be injected            – @Log, @Commons, @Log4j, @Slf4j      • Possible to implemen...
@Field      • Surprising scoping rules in scripts            – variables are local to the run() method            – variab...
Controlling code execution      • Your application may run user’s code            – what if the code runs in infinite loop...
Controlling code execution      • Your application may run user’s code            – what if the code runs in infinite loop...
Controlling code execution      • Your application may run user’s code            – what if the code runs in infinite loop...
Controlling code execution      • Your application may run user’s code            – what if the code runs in infinite loop...
@ThreadInterrupt                       @ThreadInterrupt                       import groovy.transform.ThreadInterrupt     ...
@ThreadInterrupt                       @ThreadInterrupt                       import groovy.transform.ThreadInterrupt     ...
@ThreadInterrupt                       @ThreadInterrupt                       import groovy.transform.ThreadInterrupt     ...
@TimedInterrupt                       @TimedInterrupt(10)                       import groovy.transform.TimedInterrupt    ...
@ConditionalInterrupt      • Specify your own condition to be inserted        at the start of method and closure bodies   ...
@ToString      • Provides a default toString() method to your types      • Available annotation options            – inclu...
@EqualsAndHashCode      • Provides default implementations for equals() and        hashCode() methods                     ...
@TupleConstructor      • Provides a «classical» constructor with all properties      • Several annotation parameter option...
@Canonical      • One annotation to rule them all!            – @Canonical mixes together                  •@ToString     ...
@InheritConstructor      • Classes like Exception are painful when extended,        as all the base constructors should be...
@InheritConstructor      • Classes like Exception are painful when extended,        as all the base constructors should be...
@WithReadLock, @WithWriteLock            import groovy.transform.*                          class ResourceProvider {      ...
@WithReadLock, @WithWriteLock            import groovy.transform.*                          class ResourceProvider {      ...
Miscelanous      • Compilation customizers      • Java 7 diamond operator      • Slashy and dollar slashy strings      • N...
Compilation customizers      • Ability to apply some customization to the Groovy        compilation process      • Three a...
Imports customizer         def configuration = new CompilerConfiguration()                   def custo = new ImportCustomi...
Applying an AST transformation                       def configuration = new CompilerConfiguration()                      ...
Secure AST customizer                       Idea: Implement an «arithmetic shell»                         Being able contr...
Secure AST customizer          ...          secure.with {            // disallow closure creation            closuresAllow...
Secure AST customizer        ...           // language tokens allowed           tokensWhitelist = [              PLUS, MIN...
Secure AST customizer      • Ready to evaluate our arithmetic expressions!                ...                def config = ...
Slashy and dollar slashy strings      • Slashy strings are now multiline            – particularly handy for multi-line re...
New GDK methods                        52mercredi 18 mai 2011
New GDK methods                       // count                       assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5...
New GDK methods                       // count                       assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5...
New GDK methods                       // count                       assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5...
New GDK methods                       // count                       assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5...
(G)String to Enum coercion                       enum Color {                               red, green, blue              ...
(G)String to Enum coercion                       enum Color {                               red, green, blue              ...
(G)String to Enum coercion                       enum Color {                               red, green, blue              ...
(G)String to Enum coercion                       enum Color {                               red, green, blue              ...
(G)String to Enum coercion                       enum Color {                               red, green, blue              ...
What’s                       cookingmercredi 18 mai 2011                       for 1.9?
Groovy 1.9 roadmap      • Java 7 alignements: Project Coin            – binary literals            – underscore in literal...
Groovy 1.9 roadmap      • Java 7 alignements: Project Coin            – binary literals            – underscore in literal...
Binary literals      • We had decimal, octal and hexadecimal notations        for number literals      • We can now use bi...
Underscore in literals      • We can now also add underscores        in number literals for more readability              ...
Multicatch      • One block for multiple exception caught            – rather than duplicating the block                tr...
Summary                       ROCK!                           59mercredi 18 mai 2011
Thank you!                                           e                                      aforg pment                   ...
Image credits      •   Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg      •   Bicycle: http://d...
Upcoming SlideShare
Loading in...5
×

Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011

9,774

Published on

Update on all the novelties of the recent Groovy 1.8 release, and what's cooking for 1.9.

Published in: Technology
2 Comments
16 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,774
On Slideshare
0
From Embeds
0
Number of Embeds
26
Actions
Shares
0
Downloads
134
Comments
2
Likes
16
Embeds 0
No embeds

No notes for slide

Transcript of "Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011"

  1. 1. Groovy Update What’s new in Groovy 1.8 and what’s coming next! Guillaume Laforge Groovy Project Manager SpringSource / VMwaremercredi 18 mai 2011
  2. 2. Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource / VMWare • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more... 2mercredi 18 mai 2011
  3. 3. Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource / VMWare • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more... 2mercredi 18 mai 2011
  4. 4. Groovy 1.7 3mercredi 18 mai 2011
  5. 5. Groovy 1.7 185 3mercredi 18 mai 2011
  6. 6. Groovy 1.7 185k 3mercredi 18 mai 2011
  7. 7. Groovy 1.7 185k FIRST MONTH AFTER RELEASE 3mercredi 18 mai 2011
  8. 8. Groovy 1.7 k 3mercredi 18 mai 2011
  9. 9. Groovy 1.7 177k SECOND MONTH AFTER RELEASE 3mercredi 18 mai 2011
  10. 10. Groovy 1.7 k 3mercredi 18 mai 2011
  11. 11. Groovy 1.7 362k USERS? 3mercredi 18 mai 2011
  12. 12. ? TIP OF THEmercredi 18 mai 2011 ICEBERG
  13. 13. Agenda •What’s new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations – Miscelanous 5mercredi 18 mai 2011
  14. 14. Agenda •What’s new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations – Miscelanous •What’s cooking for Groovy 1.9? – Continued runtime performance improvements – Alignments with JDK 7 •Project Coin (small language changes) •InvokeDynamic 5mercredi 18 mai 2011
  15. 15. Command chains expressions 6mercredi 18 mai 2011
  16. 16. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 6mercredi 18 mai 2011
  17. 17. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 6mercredi 18 mai 2011
  18. 18. Command chains expressions • 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) 6mercredi 18 mai 2011
  19. 19. Command chains expressions • 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) 6mercredi 18 mai 2011
  20. 20. Command chains expressions • 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) • Let’s have a look at some examples 6mercredi 18 mai 2011
  21. 21. Command chains expressions  turn left  then right  7mercredi 18 mai 2011
  22. 22. Command chains expressions Alternation of method names  turn left  then right  7mercredi 18 mai 2011
  23. 23. Command chains expressions Alternation of method names  turn left  then right  and parameters (even named ones) 7mercredi 18 mai 2011
  24. 24. Command chains expressions  turn left  then right  7mercredi 18 mai 2011
  25. 25. Command chains expressions Equivalent to:      (    ).    (     )  turn left  then right  7mercredi 18 mai 2011
  26. 26. LookM a! N op are ns, no do ts!mercredi 18 mai 2011
  27. 27. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours 9mercredi 18 mai 2011
  28. 28. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument 9mercredi 18 mai 2011
  29. 29. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments 9mercredi 18 mai 2011
  30. 30. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments Woud call: def take(Map m, Quantity q) 9mercredi 18 mai 2011
  31. 31. Command chains expressions Now, even less punctuation! take 2.pills  of  chloroquinine  after  6.hours 10mercredi 18 mai 2011
  32. 32. Command chains expressions Now, even less punctuation!     (       ).   (             ).      (       ) take 2.pills  of  chloroquinine  after  6.hours 10mercredi 18 mai 2011
  33. 33. Command chains expressions // environment initialization Integer.metaClass.getPills { ‐> delegate } Integer.metaClass.getHours { ‐> delegate }   // variable injection def chloroquinine = /*...*/   { } // implementing the DSL logic def take(n) {     [of: { drug ‐>         [after: { time ‐> /*...*/ }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2.pills of chloroquinine after 6.hours 11mercredi 18 mai 2011
  34. 34. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours 12mercredi 18 mai 2011
  35. 35. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours ... some dots remain ... 12mercredi 18 mai 2011
  36. 36. Command chains expressions We could cheat a bit... take 2  pills of  chloroquinine 6  hours after 13mercredi 18 mai 2011
  37. 37. Command chains expressions We could cheat a bit...     ( ).     (  ).             ( ).     (     ) take 2  pills of  chloroquinine 6  hours after 13mercredi 18 mai 2011
  38. 38. Cheating is playing with the languagemercredi 18 mai 2011
  39. 39. Command chains expressions Still doable without cheating though take 2  pills of  chloroquinine after  6 hours 15mercredi 18 mai 2011
  40. 40. Command chains expressions Still doable without cheating though     ( ).     (  ).             (     ). (     ) take 2  pills of  chloroquinine after  6 hours 15mercredi 18 mai 2011
  41. 41. Command chains expressions // variable injection def (of, after, hours) = /*...*/   // implementing the DSL logic { } def take(n) {     [pills: { of ‐>         [chloroquinine: { after ‐>             [6: { time ‐> }]         }]     }] } // ‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take 2 pills of chloroquinine after 6 hours 16mercredi 18 mai 2011
  42. 42. Command chains expressions 17mercredi 18 mai 2011
  43. 43. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor 17mercredi 18 mai 2011
  44. 44. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation check that: margarita  tastes good 17mercredi 18 mai 2011
  45. 45. Command chains expressions // 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 {} 17mercredi 18 mai 2011
  46. 46. Command chains expressions // 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 17mercredi 18 mai 2011
  47. 47. Command chains expressions // 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 17mercredi 18 mai 2011
  48. 48. Command chains expressions // 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 17mercredi 18 mai 2011
  49. 49. Command chains expressions // 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 17mercredi 18 mai 2011
  50. 50. Command chains expressions // 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 17mercredi 18 mai 2011
  51. 51. Command chains expressions // 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 17mercredi 18 mai 2011
  52. 52. Command chains expressions // 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     ( ). 17mercredi 18 mai 2011
  53. 53. Runtime perf. improvements • Significant runtime improvements for primitive int operations – classical Fibonacci example x13 faster! – almost as fast as Java • Some direct method calls on this • But there’s more to come! – in particular for all the primitive types • But Jochen «blackdrag» will tell you more on that! 18mercredi 18 mai 2011
  54. 54. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms – actors, fork/join, dataflow, agents, STM... • Václav Pech will cover the details on GPars 19mercredi 18 mai 2011
  55. 55. Closure enhancements • Closure annotation parameters • Some more functional flavor – composition – trampoline – memoization • Currying improvements 20mercredi 18 mai 2011
  56. 56. Closure annotation parameters @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) 21mercredi 18 mai 2011
  57. 57. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {         Class value() // a closure class }   { @Invariant({ number >= 0 }) class Distance {         float number     P oor-m miss Cont Andr racts an’s G é’s talk!     String unit Don’t }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) 21mercredi 18 mai 2011
  58. 58. Closure composition def plus2  = { it + 2 } def times3 = { it * 3 }    { def times3plus2 = plus2 << times3 assert times3plus2(3) == 11 assert times3plus2(4) == plus2(times3(4))    { def plus2times3 = times3 << plus2 assert plus2times3(3) == 15 assert plus2times3(5) == times3(plus2(5))    // reverse composition { assert times3plus2(3) == (times3 >> plus2)(3) 22mercredi 18 mai 2011
  59. 59. Closure trampoline 23mercredi 18 mai 2011
  60. 60. Closure trampoline def factorial factorial = { int n, BigInteger accu = 1G ‐>        if (n < 2) return accu          factorial.trampoline(n ‐ 1, n * accu) }.trampoline()   assert factorial(1)    == 1 assert factorial(3)    == 1 * 2 * 3 assert factorial(1000) == 402387260... 23mercredi 18 mai 2011
  61. 61. Closure memoization 24mercredi 18 mai 2011
  62. 62. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() 24mercredi 18 mai 2011
  63. 63. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms 24mercredi 18 mai 2011
  64. 64. 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 24mercredi 18 mai 2011
  65. 65. 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 24mercredi 18 mai 2011
  66. 66. 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   24mercredi 18 mai 2011
  67. 67. 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     24mercredi 18 mai 2011
  68. 68. 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)   24mercredi 18 mai 2011
  69. 69. 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)  24mercredi 18 mai 2011
  70. 70. 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) 24mercredi 18 mai 2011
  71. 71. Currying improvements 25mercredi 18 mai 2011
  72. 72. Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     25mercredi 18 mai 2011
  73. 73. Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     // currying n‐th parameter def joinWithSeparator =      { one, sep, two ‐> one + sep + two } def joinWithComma =      joinWithSeparator.ncurry(1, , ) assert joinWithComma(a, b) == a, b 25mercredi 18 mai 2011
  74. 74. Builtin JSON support • Consuming • Producing • Pretty-printing 26mercredi 18 mai 2011
  75. 75. 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 } 27mercredi 18 mai 2011
  76. 76. Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {         name "Guillaume"     age 33         pets "Hector", "Felix" }  println json.toString() 28mercredi 18 mai 2011
  77. 77. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":33, +      "pets":["Hector","Felix"]}})   29mercredi 18 mai 2011
  78. 78. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":33, +      "pets":["Hector","Felix"]}})   {         "person": {                 "name": "Guillaume",              "age": 33,                 "pets": [                         "Hector",                         "Felix"                 ]         } } 29mercredi 18 mai 2011
  79. 79. New AST transformations • @Log • @Canonical – @ToString, • @Field – @EqualsAndHashCode, – @TupleConstructor • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • Controlling the execution of your code • @WithWriteLock – @ThreadInterrupt, – @TimedInterrupt, • @ListenerList – @ConditionalInterrupt 30mercredi 18 mai 2011
  80. 80. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {         Car() {                 log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
  81. 81. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    @Log class Car {     Guarded     Car() {         w/ an if         log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
  82. 82. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import groovy.util.logging.*    Hackerg @Log arten class Car {     certified! Guarded     Car() {         w/ an if         log.info Car constructed         } }    def c = new Car() 31mercredi 18 mai 2011
  83. 83. @Field • Surprising scoping rules in scripts – variables are local to the run() method – variables aren’t visible in methods •although visually the variable is in a surrounding scope • @Field creates a field in the script class @Field List awe = [1, 2, 3] def awesum() { awe.sum() } assert awesum() == 6 32mercredi 18 mai 2011
  84. 84. 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? 33mercredi 18 mai 2011
  85. 85. 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 33mercredi 18 mai 2011
  86. 86. 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 33mercredi 18 mai 2011
  87. 87. 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 • Also see compilation customizers later on 33mercredi 18 mai 2011
  88. 88. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) {     // eat lots of CPU } 34mercredi 18 mai 2011
  89. 89. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } 34mercredi 18 mai 2011
  90. 90. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } • Two optional annotation parameters available – checkOnMethodStart (true by default) – applyToAllClasses (true by default) 34mercredi 18 mai 2011
  91. 91. @TimedInterrupt @TimedInterrupt(10) import groovy.transform.TimedInterrupt    while (true) {     // eat lots of CPU } • InterruptedException thrown when checks indicate code ran longer than desired • Optional annotation parameters available – same as @ThreadInterrupt – value: for an amount of time duration – unit: for the time duration unit (TimeUnit.SECONDS) 35mercredi 18 mai 2011
  92. 92. @ConditionalInterrupt • Specify your own condition to be inserted at the start of method and closure bodies – check for available resources, number of times run, etc. • Leverages the new closure annotation parameter feature of Groovy 1.8 @ConditionalInterrupt({ counter++ > 2 }) import groovy.transform.ConditionalInterrupt import groovy.transform.Field    @Field int counter = 0  100.times {         println executing script method... } 36mercredi 18 mai 2011
  93. 93. @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) 37mercredi 18 mai 2011
  94. 94. @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() 38mercredi 18 mai 2011
  95. 95. @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, 3)         assert m.name == Marion assert m.age  == 3 39mercredi 18 mai 2011
  96. 96. @Canonical • One annotation to rule them all! – @Canonical mixes together •@ToString •@EqualsAndHashCode •@TupleConstructor • You can customize behavior by combining @Canonical and one of the other annotations 40mercredi 18 mai 2011
  97. 97. @InheritConstructor • 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)      } } 41mercredi 18 mai 2011
  98. 98. @InheritConstructor • 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)      } } 41mercredi 18 mai 2011
  99. 99. @WithReadLock, @WithWriteLock import groovy.transform.*    class ResourceProvider {         private final Map<String, String> data = new HashMap<>()       @WithReadLock         String getResource(String key) {                 return data.get(key)         }            @WithWriteLock         void refresh() {                 //reload the resources into memory         } } 42mercredi 18 mai 2011
  100. 100. @WithReadLock, @WithWriteLock import groovy.transform.*    class ResourceProvider {         private final Map<String, String> data = new HashMap<>()   {     @WithReadLock         String getResource(String key) {                 return data.get(key)         }        {     @WithWriteLock         void refresh() {                 //reload the resources into memory         } } 42mercredi 18 mai 2011
  101. 101. Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion 43mercredi 18 mai 2011
  102. 102. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers – ImportCustomizer – SecureASTCustomizer – ASTTransformationCustomizer • But you can implement your own 44mercredi 18 mai 2011
  103. 103. Imports customizer def configuration = new CompilerConfiguration()   def custo = new ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)    def result = new GroovyShell(configuration)     .evaluate(" cos PI/3 ") 45mercredi 18 mai 2011
  104. 104. Applying an AST transformation def configuration = new CompilerConfiguration() configuration.addCompilationCustomizers(     new ASTTransformationCustomizer(Log))    new GroovyShell(configuration).evaluate("""     class Car {                 Car() {                         log.info Car constructed                 }         }          log.info Constructing a car         def c = new Car() """) 46mercredi 18 mai 2011
  105. 105. Secure AST customizer Idea: Implement an «arithmetic shell» Being able control what a user script is allowed to do: only arithmetic expressions • Let’s setup our environment – some imports – an import customizer to import java.lang.Math.* – prepare a secure AST customizer import org.codehaus.groovy.control.customizers.* import org.codehaus.groovy.control.* import static org.codehaus.groovy.syntax.Types.*   def imports = new ImportCustomizer().addStaticStars(java.lang.Math) def secure = new SecureASTCustomizer() ... 47mercredi 18 mai 2011
  106. 106. Secure AST customizer ... secure.with { // disallow closure creation closuresAllowed = false  // disallow method definitions methodDefinitionAllowed = false    // empty white list => forbid imports importsWhitelist = []  staticImportsWhitelist = [] // only allow the java.lang.Math.* static import staticStarImportsWhitelist = [java.lang.Math ... 48mercredi 18 mai 2011
  107. 107. Secure AST customizer ... // language tokens allowed tokensWhitelist = [ PLUS, MINUS, MULTIPLY, DIVIDE, MOD, POWER, PLUS_PLUS,  MINUS_MINUS, COMPARE_EQUAL, COMPARE_NOT_EQUAL,  COMPARE_LESS_THAN, COMPARE_LESS_THAN_EQUAL,  COMPARE_GREATER_THAN, COMPARE_GREATER_THAN_EQUAL ]   // types allowed to be used (including primitive types) constantTypesClassesWhiteList = [ Integer, Float, Long, Double, BigDecimal,  Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE ]   // classes who are allowed to be receivers of method calls receiversClassesWhiteList = [  Math, Integer, Float, Double, Long, BigDecimal ] } ... 49mercredi 18 mai 2011
  108. 108. Secure AST customizer • Ready to evaluate our arithmetic expressions! ... def config = new CompilerConfiguration() config.addCompilationCustomizers(imports, secure) def shell = new GroovyShell(config)   shell.evaluate cos(PI/3) • But the following would have failed: shell.evaluate System.exit(0) 50mercredi 18 mai 2011
  109. 109. Slashy and dollar slashy strings • Slashy strings are now multiline – particularly handy for multi-line regexs • Dollar slashy string notation introduced – a multiline GString with different escaping rules def (name, date) = ["Guillaume", "May, 17th"] def dollarSlashy = $/         Hello $name, today were ${date}     $ dollar‐sign         $$ dollar‐sign          backslash         / slash        $/ slash /$  51mercredi 18 mai 2011
  110. 110. New GDK methods 52mercredi 18 mai 2011
  111. 111. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   52mercredi 18 mai 2011
  112. 112. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   52mercredi 18 mai 2011
  113. 113. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   // min/max for maps with closures def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == dddd assert map.min { it.value }.value == 1   52mercredi 18 mai 2011
  114. 114. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by assert [0:2, 1:3] == [1,2,3,4,5].countBy{ it % 2 } assert [(true):2, (false):4]      == Groovy.toList().countBy{ it == o }   // min/max for maps with closures def map = [a: 1, bbb: 4, cc: 5, dddd: 2]  assert map.max { it.key.size() }.key == dddd assert map.min { it.value }.value == 1   // map withDefault() def words = "one two two three three three".split() def freq = [:].withDefault { k ‐> 0 } words.each { freq[it] += 1 } 52mercredi 18 mai 2011
  115. 115. (G)String to Enum coercion enum Color {         red, green, blue }  53mercredi 18 mai 2011
  116. 116. (G)String to Enum coercion enum Color {         red, green, blue }    53mercredi 18 mai 2011
  117. 117. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    53mercredi 18 mai 2011
  118. 118. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    53mercredi 18 mai 2011
  119. 119. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    // with GStrings too def g = "${green}" as Color 53mercredi 18 mai 2011
  120. 120. What’s cookingmercredi 18 mai 2011 for 1.9?
  121. 121. Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Rewritten Antlr 3 grammar (GSoC) • Eclipse compiler to replace the joint compiler? • What else? Your call! 55mercredi 18 mai 2011
  122. 122. Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Rewritten Antlr 3 grammar (GSoC) • Eclipse compiler to replace the joint compiler? • What else? Your call! 55mercredi 18 mai 2011
  123. 123. 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 56mercredi 18 mai 2011
  124. 124. Underscore in literals • We can now 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 57mercredi 18 mai 2011
  125. 125. Multicatch • One block for multiple exception caught – rather than duplicating the block try {     /* ... */ } catch(IOException | NullPointerException e) {     /* one block to treat 2 exceptions */ } 58mercredi 18 mai 2011
  126. 126. Summary ROCK! 59mercredi 18 mai 2011
  127. 127. Thank you! e aforg pment ume L Develo Guilla Groovy om He ad of e@ gmail.c glaforg rge Email: @glafo : Twitter 60mercredi 18 mai 2011
  128. 128. Image credits • Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg • Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2 • 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 • Cheating: http://fr.academic.ru/pictures/frwiki/67/Cheating.JPG • Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/ • Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg • Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg • Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg • Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg 61mercredi 18 mai 2011
  1. A particular slide catching your eye?

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

×