Groovy Update - Guillaume Laforge - Greach 2011

2,202 views

Published on

Overview of the features of Groovy 1.8 and what is coming in the next major version.

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,202
On SlideShare
0
From Embeds
0
Number of Embeds
254
Actions
Shares
0
Downloads
39
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Groovy Update - Guillaume Laforge - Greach 2011

  1. 1. Whatʼs new in Groovy 1.8 and beyond?Guillaume LaforgeGroovy Project ManagerSpringSource, a division of VMwareTwitter: @glaforgeBlog: http://glaforge.appspot.comGoogle+: http://gplus.to/glaforge
  2. 2. Guillaume Laforge• Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk toolkit• Co-author of Groovy in Action• Speaking worldwide w/ a French accent• Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 2
  3. 3. Guillaume Laforge• Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk toolkit• Co-author of Groovy in Action• Speaking worldwide w/ a French accent• Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 2
  4. 4. Groovy 1.7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  5. 5. Groovy 1.7185 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  6. 6. Groovy 1.7185k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  7. 7. Groovy 1.7185k FIRST MONTH AFTER RELEASE @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  8. 8. Groovy 1.7 k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  9. 9. Groovy 1.7177k SECOND MONTH AFTER RELEASE @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  10. 10. Groovy 1.7 k @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  11. 11. Groovy 1.7362k USERS? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 3
  12. 12. ?TIP OFTHEICEBERG
  13. 13. Guesstimate 1/2 Users Million@glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 5
  14. 14. Agenda @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  15. 15. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  16. 16. 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• Whatʼs cooking for Groovy 1.9? – Continued runtime performance improvements – Alignments with JDK 7 • Project Coin (small language changes) • Static type checking • InvokeDynamic @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 6
  17. 17. Command chains expressions @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  21. 21. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  22. 22. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 7
  23. 23. Command chains expressions  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  24. 24. Command chains expressions Alternation of method names  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  25. 25. Command chains expressions Alternation of method names  turn left  then right  and parameters (even named ones) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  26. 26. Command chains expressions  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  27. 27. Command chains expressions Equivalent to:      (    ).    (     )  turn left  then right  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 8
  28. 28. LookM a!N op are ns,no do ts!
  29. 29. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  30. 30. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  31. 31. Command chains expressions Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  32. 32. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 10
  33. 33. Command chains expressions Now, even less punctuation! take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
  34. 34. Command chains expressions Now, even less punctuation!     (       ).   (             ).      (       ) take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 11
  35. 35. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 12
  36. 36. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
  37. 37. Command chains expressions take 2.pills  of  chloroquinine  after  6.hours ... some dots remain ... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 13
  38. 38. Command chains expressions Yes, we can... get rid of them :-) take 2  pills of  chloroquinine  after  6 hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
  39. 39. Command chains expressions Yes, we can... get rid of them :-)     ( ).     (  ).              (     ). (     ) take 2  pills of  chloroquinine  after  6 hours @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 14
  40. 40. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 15
  41. 41. Command chains expressions @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  42. 42. Command chains expressions // methods with multiple arguments (commas) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  43. 43. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  44. 44. Command chains expressions // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named‐args as punctuation @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 {} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  53. 53. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  54. 54. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  55. 55. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  56. 56. 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     ( ). @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  57. 57. Runtime performance improvements• Significant runtime improvements for primitive type operations – classical Fibonacci example x13 faster! – almost as fast as Java• Some direct method calls on this @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 17
  58. 58. 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, STM – parallel arrays, executors, and more... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 18
  59. 59. Closure enhancements• Closure annotation parameters• Some more functional flavor – composition – trampoline – memoization• Currying improvements @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 19
  60. 60. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 20
  61. 61. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {         Class value() // a closure class }  { @Invariant({ number >= 0 }) class Distance {         float number     an’s G Cont racts     String unit P oor-m }    def d = new Distance(number: 10, unit: "meters")  def anno = Distance.getAnnotation(Invariant) def check = anno.value().newInstance(d, d) assert check(d) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 20
  62. 62. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
  63. 63. Closure trampoline @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
  64. 64. 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... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 22
  65. 65. Closure memoization @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  66. 66. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  67. 67. Closure memoization def plus = { a, b ‐> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  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   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  71. 71. 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     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  72. 72. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  73. 73. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  74. 74. 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)   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  75. 75. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  76. 76. 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)  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  77. 77. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  78. 78. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 23
  79. 79. Currying improvements @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  80. 80. Currying improvements // right currying def divide = { a, b ‐> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  81. 81. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 24
  82. 82. Builtin JSON support• Consuming• Producing• Pretty-printing @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 25
  83. 83. Builtin JSON supportimport 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 26
  84. 84. Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {         name "Guillaume"     age 33         pets "Hector", "Felix" }  println json.toString() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 27
  85. 85. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint(     {"person":{"name":"Guillaume","age":33, +      "pets":["Hector","Felix"]}})   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
  86. 86. 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"                 ]         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 28
  87. 87. New AST transformations• @Log • @Canonical – @ToString,• @Field – @EqualsAndHashCode, – @TupleConstructor• @AutoClone• @AutoExternalizable • @InheritConstructor • @WithReadLock• Controlling the execution of your code • @WithWriteLock – @ThreadInterrupt, – @TimedInterrupt, • @ListenerList – @ConditionalInterrupt @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 29
  88. 88. @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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 30
  89. 89. @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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 30
  90. 90. @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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 31
  91. 91. 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? @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  92. 92. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  93. 93. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  94. 94. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 32
  95. 95. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) {     // eat lots of CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  96. 96. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { {     if (Thread.currentThread.isInterrupted())         throw new InterruptedException() }     // eat lots of CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  97. 97. @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) 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 33
  98. 98. @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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 34
  99. 99. @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 closure annotation parameters from Groovy 1.8 @ConditionalInterrupt({ counter++ > 2 }) import groovy.transform.ConditionalInterrupt import groovy.transform.Field    @Field int counter = 0  100.times {         println executing script method... } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 35
  100. 100. @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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 36
  101. 101. @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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 37
  102. 102. @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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 38
  103. 103. @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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 39
  104. 104. @InheritConstructor• Classes like Exception are painful when extended, as all the base constructors should be replicatedclass CustomException extends Exception {    CustomException()                        { super()       }    CustomException(String msg)              { super(msg)    }    CustomException(String msg, Throwable t) { super(msg, t) }    CustomException(Throwable t)             { super(t)      }} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
  105. 105. @InheritConstructor• Classes like Exception are painful when extended, as all the base constructors should be replicatedimport groovy.transform.*@InheritConstructorsclass CustomException extends Exception {    CustomException()                        { super()       }    CustomException(String msg)              { super(msg)    }    CustomException(String msg, Throwable t) { super(msg, t) }    CustomException(Throwable t)             { super(t)      }} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 40
  106. 106. @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         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
  107. 107. @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         } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 41
  108. 108. Miscelanous• Compilation customizers• Java 7 diamond operator• Slashy and dollar slashy strings• New GDK methods• (G)String to Enum coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 42
  109. 109. Compilation customizers• Ability to apply some customization to the Groovy compilation process• Three available customizers – ImportCustomizer – ASTTransformationCustomizer – SecureASTCustomizer• But you can implement your own @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 43
  110. 110. 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 ") @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 44
  111. 111. 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() """) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 45
  112. 112. 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 customizerimport 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 46
  113. 113. 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 ... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 47
  114. 114. 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 ]}... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 48
  115. 115. 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) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 49
  116. 116. 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", "Oct, 26th"] def dollarSlashy = $/         Hello $name, today were ${date}     $ dollar‐sign         $$ dollar‐sign          backslash         / slash        $/ slash /$  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 50
  117. 117. New GDK methods @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  118. 118. New GDK methods // count @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  119. 119. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  120. 120. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  121. 121. New GDK methods // count assert [2,4,2,1,3,5,2,4,3].count { it % 2 == 0 } == 5   // count by @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  122. 122. 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  123. 123. 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  124. 124. 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 }   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  125. 125. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  126. 126. 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]  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  127. 127. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  128. 128. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  129. 129. 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   @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  130. 130. 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  131. 131. 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() @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  132. 132. 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  133. 133. 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 } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 51
  134. 134. (G)String to Enum coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  135. 135. (G)String to Enum coercion enum Color {     @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  136. 136. (G)String to Enum coercion enum Color {         red, green, blue @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  137. 137. (G)String to Enum coercion enum Color {         red, green, blue }  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  138. 138. (G)String to Enum coercion enum Color {         red, green, blue }    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  139. 139. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  140. 140. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  141. 141. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  142. 142. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  143. 143. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"  @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  144. 144. (G)String to Enum coercion enum Color {         red, green, blue }    // coercion with as def r = "red" as Color    // implicit coercion Color b = "blue"    @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  145. 145. (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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  146. 146. (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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 52
  147. 147. Customizing the Groovysh prompt @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 53
  148. 148. Launching remote scripts• With the Groovy command, you can launch remote scripts > groovy http://groovyconsole.appspot.com/raw/110001• Be careful to what youʼre executing :-) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 54
  149. 149. What’scookingfor 1.9?
  150. 150. Groovy 1.9 roadmap• Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking and compilation• Miscelanous• What else? Your call! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 56
  151. 151. Groovy 1.9 roadmap• Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch• JDK 7: InvokeDynamic• Towards a more modular Groovy• Static type checking and compilation• Miscelanous• What else? Your call! @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 56
  152. 152. Java 7 / JDK 7• Project Coin and InvokeDynamic @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 57
  153. 153. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 58
  154. 154. 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 59
  155. 155. Multicatch• One block for multiple exception caught – rather than duplicating the block try {     /* ... */ } catch(IOException | NullPointerException e) {     /* one block to treat 2 exceptions */ } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 60
  156. 156. InvokeDynamic• Groovy 1.9 will support JDK 7ʼs invokeDynamic – an «indy» branch started recently – compiler will have a flag for compiling against JDK 7• Benefits – more runtime performance! – 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 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 61
  157. 157. Groovy Modularity• Groovyʼs «all» JAR weighs in at 4MB• 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 EMCs / DGM methods, etc. @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 62
  158. 158. 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... @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 63
  159. 159. A typo in your variable or method namesimport groovy.transform.StaticTypes void method() {} @TypeChecked test() {    // Cannot find matching method metthhoood()    metthhoood()     def name = "Guillaume"    // variable naamme is undeclared    println naamme} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 64
  160. 160. A typo in your variable or method namesimport groovy.transform.StaticTypes void method() {} @TypeChecked test() {    // Cannot find matching method metthhoood()    metthhoood()     def name = "Guillaume"    // variable naamme is undeclared Compilation    println naamme errors!} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 64
  161. 161. Complain on 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 = 0i += 1 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 65
  162. 162. Complain on 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 = 0i += 1 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 65
  163. 163. Complain on wrong return typesString method() { String }// cannot assign value of type String...int x = method()// checks if/else branch return valuesint method() {    if (true) { String }    else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) {    def sb = new StringBuilder()    sb << "Hi" << name} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 66
  164. 164. Complain on wrong return typesString method() { String }// cannot assign value of type String...int x = method() Compilation errors!// checks if/else branch return valuesint method() {    if (true) { String }    else { 42 }}// works for switch/case & try/catch/finally // transparent toString() impliedString greeting(String name) {    def sb = new StringBuilder()    sb << "Hi" << name} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 66
  165. 165. 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     } } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 67
  166. 166. Staticly checked method & dynamic method @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() } @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 68
  167. 167. Bytecode viewer• Groovy Consoleʼs bytecode viewer from the AST browser window – select class generation phase – select a class node @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 69
  168. 168. Disable Global AST transformations// witout a specific configuration, the AST builder worksdef shell = new GroovyShell()shell.evaluate(script) // passesdef config = new CompilerConfiguration()config.disabledGlobalASTTransformations =    [org.codehaus.groovy.ast.builder.AstBuilderTransformation]def script =     import org.codehaus.groovy.ast.builder.AstBuilder    new AstBuilder().buildFromCode { "Hello" } // now with the configuration in place,// the AST builder transform is not appliedshell = new GroovyShell(config) // <‐‐ with the configurationshouldFail {    shell.evaluate(script) // fails} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 70
  169. 169. Summary @glaforge — http://glaforge.appspot.com ROCKS! — http://gplus.to/glaforge 71
  170. 170. Thank you! e L aforg pment aume vy Develo Guill Groo m Hea d of g mail.co aforge@ mail: gl glaforge e E @ o /glaforg T witter : http://gplus.t Go ogle+: @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 72
  171. 171. Q&A — Got questions, Really?
  172. 172. 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• 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• Caution: http://www.jeunes-epinay-sur-seine.fr/wp-content/uploads/2010/11/caution-colocation.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• WIP: http://www.connetport.com/wp-content/uploads/Work_in_progress.svg_.png• Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg• @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 74

×