SlideShare una empresa de Scribd logo
1 de 122
What’s new in Groovy?
Groovy 1.8 and what’s ahead
Guillaume Laforge                          @glaforge
Groovy Project Manager   http://glaforge.appspot.com
SpringSource / VMware         http://gplus.to/glaforge
Guillaume Laforge
• Groovy Project Manager at VMware
 • Initiator of the Grails framework
 • Creator of the Gaelyk toolkit


• Co-author of Groovy in Action

• Follow me on...
 • My blog: http://glaforge.appspot.com
 • Twitter: @glaforge
 • Google+: http://gplus.to/glaforge
                                          2
Agenda

• What’s new in Groovy 1.8?
 –Nicer DSLs with command chains
 –Runtime performance improvements
 –GPars bundled for taming your multicores
 –Closure enhancements
 –Builtin JSON support
 –New AST transformations




                                             3
Agenda

• What’s cooking for Groovy 2.0?
 –Alignments with JDK 7
   • Project Coin (small language changes)
   • InvokeDynamic
     – Continued runtime performance improvements
 –Static type checking and compilation




                                                    4
Command chains

• A grammar improvement allowing you
  to drop dots & parens
  when chaining method calls
 –an extended version of top-level statements like println


• Less dots, less parens allow you to
 –write more readable business rules
 –in almost plain English sentences
   • (or any language, of course)

                                                         5
Command chains




     turn left then right




                            6
Command chains

     Alternation of
     method names




     turn left then right




                            6
Command chains

     Alternation of
     method names




     turn left then right


                        and parameters
                      (even named ones)


                                          6
Command chains




     turn left then right




                            6
Command chains



     Equivalent to:


      turn left then) right
         ( ). (




                              6
LookM  a!
N op are ns,
no do ts!
Command chains


   Before... we used to do...


 take 2.pills, of: chloroquinine, after: 6.hours




                                                   8
Command chains


   Before... we used to do...


 take 2.pills, of: chloroquinine, after: 6.hours


   Normal argument




                                                   8
Command chains


   Before... we used to do...


 take 2.pills, of: chloroquinine, after: 6.hours


   Normal argument              Named arguments




                                                   8
Command chains


   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)

                                                   8
Command chains


  Now, even less punctuation!


 take 2 pills of chloroquinine after 6 hours




                                               9
Command chains


  Now, even less punctuation!


 take).2 pills of chloroquinine )
    (     ( ).         (  ). (  after 6 hours




                                                9
Command chains

    // Java fluent API approach
    class RegimenBuilder {
       ...
       def take(int n) {
           this.pills = n
           return this
       }

        def pills(String of) {
            return this
        }
        ...
    }


                                 10
Command chains

     // 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

                                                       11
Command chains




                 12
Command chains
 // methods with multiple arguments (commas)




                                               12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor




                                               12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation




                                               12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good




                                               12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures




                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}




                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens




                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens
 select all  unique() from names



                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms

                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies
                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
    (   ). (         ). (   )

 // leverage named-args as punctuation
 check that: margarita  tastes good

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies
                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
    (   ). (         ). (   )

 // leverage named-args as punctuation
 check that: margarita  )tastes good
     (         ).  (

 // closure parameters for new control structures
 given {}  when {}  then {}

 // zero-arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies
                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
    (   ). (         ). (   )

 // leverage named-args as punctuation
 check that: margarita  )tastes good
     (         ).  (

 // closure parameters for new control structures
 given). when {}  )
    ( {}  ( ). ( then {}

 // zero-arg methods require parens
 select all  unique() from names

 // possible with an odd number of terms
 take 3  cookies
                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
    (   ). (         ). (   )

 // leverage named-args as punctuation
 check that: margarita  )tastes good
     (         ).  (

 // closure parameters for new control structures
 given). when {}  )
    ( {}  ( ). ( then {}

 // zero-arg methods require parens
 select all  unique() from names
     ( ).       . (     )

 // possible with an odd number of terms
 take 3  cookies
                                                    12
Command chains
 // methods with multiple arguments (commas)
 take coffee  with sugar, milk  and liquor
    (   ). (         ). (   )

 // leverage named-args as punctuation
 check that: margarita  )tastes good
     (         ).  (

 // closure parameters for new control structures
 given). when {}  )
    ( {}  ( ). ( then {}

 // zero-arg methods require parens
 select all  unique() from names
     ( ).       . (     )

 // possible with an odd number of terms
 take).3  cookies
    (
                                                    12
Runtime performance

• Significant runtime improvements
  for primitive type operations
 –classical Fibonacci example x13 faster!
 –closer to Java performance


• Some direct method calls on this




                                            13
GPars bundled

• GPars is bundled
  in the Groovy distribution



• GPars covers a wide range of parallel and
  concurrent paradigms
  –actors, fork/join, map/filter/reduce, dataflow, agents
  –parallel arrays, executors, STM, and more...


                                                            14
Closure enhancements

• Closure annotation parameters

• Some more functional flavor
 –composition
 –trampoline
 –memoization


• Currying improvements

                                  15
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)
                                                        16
Closure annotation parameters
    @Retention(RetentionPolicy.RUNTIME)
    @interface Invariant {    
       Class value() // a closure class
    }


{
     
    @Invariant({ number >= 0 })
    class Distance {    
                                                 GCon tracts
       float number                    oor-m an’s
                                    P
       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)
                                                               16
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)
                                                    17
Closure trampoline




                     18
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...



                                                    18
Closure memoization




                      19
Closure memoization
 def plus = { a, b -> sleep 1000; a + b }.memoize()




                                                      19
Closure memoization
 def plus = { a, b -> sleep 1000; a + b }.memoize()

 assert plus(1, 2) == 3 // after 1000ms




                                                      19
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




                                                      19
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




                                                      19
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  




                                                              19
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  
  




                                                              19
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




                                                      19
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)




                                                      19
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)
  




                                                      19
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




                                                      19
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) 



                                                      19
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

                                                      19
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)
                                                      19
Currying improvements




                        20
Currying improvements

  // right currying
  def divide = { a, b -> a / b }
  def halver = divide.rcurry(2)
  assert halver(8) == 4  
   




                                   20
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'
                                             20
Builtin JSON support

• Consuming

• Producing

• Pretty-printing




                       21
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 }




                                                22
Builtin JSON support

 import groovy.json.* 
  
 def json = new JsonBuilder() 
  
 json.person {    
    name "Guillaume"
    age 34    
    pets "Hector", "Felix"
 } 
 println json.toString()

                                 23
Builtin JSON support

 import groovy.json.* 
  
 def json = new JsonBuilder() 
  
 json.person {             {    
    name "Guillaume"           "person": {        
                                 "name": "Guillaume",        
    age 34                       "age": 34,        
    pets "Hector", "Felix"       "pets": [            
 }                                   "Hector",            
                                     "Felix"        
 println json.toString()         ]    
                                     }
                                 }
                                                                23
Builtin JSON support

  import groovy.json.* 
   
  println JsonOutput.prettyPrint(
     '''{"person":{"name":"Guillaume","age":34,''' +
     '''"pets":["Hector","Felix"]}}''')
   

                 {    
                     "person": {        
                       "name": "Guillaume",        
                       "age": 34,        
                       "pets": [            
                           "Hector",            
                           "Felix"        
                       ]    
                     }
                 }
                                                       24
New AST transformations
• @Log                        • @Canonical
                                – @ToString,
• @Field                        – @EqualsAndHashCode,
                                – @TupleConstructor

• @AutoClone
                              • @InheritConstructor
• @AutoExternalizable

                              • @WithReadLock
• Controlling the execution
  of your code                • @WithWriteLock
  – @ThreadInterrupt,
  – @TimedInterrupt,          • @ListenerList
  – @ConditionalInterrupt
                                                        25
@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()
                                                    26
@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()
                                                    26
@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

                                                                 27
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?




                                                             28
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

                                                             28
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                  28
@ThreadInterrupt
   @ThreadInterrupt
   import groovy.transform.ThreadInterrupt 
    
   while (true) {


       // eat lots of CPU
   }




                                              29


                                                   33
@ThreadInterrupt
      @ThreadInterrupt
      import groovy.transform.ThreadInterrupt 
       
      while (true) {

  {     if (Thread.currentThread.isInterrupted())
            throw new InterruptedException()        }
        // eat lots of CPU
      }




                                                        29


                                                             33
@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)
                                                        29


                                                             33
@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) 30
@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...'
       }
                                                               31
@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)

                                                          32
@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()


                                                     33
@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
                                                    34
@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


                                                35
@InheritConstructors
• Classes like Exception are painful when
  extended, as all the base constructors should
  be replicated



class CustomException extends Exception {
   CustomException()               { super()     }
   CustomException(String msg)         { super(msg) }
   CustomException(String msg, Throwable t) { super(msg, t) }
   CustomException(Throwable t)         { super(t)   }
}



                                                                36
@InheritConstructors
• Classes like Exception are painful when
  extended, as all the base constructors should
  be replicated

import groovy.transform.*

@InheritConstructors
class CustomException extends Exception {
   CustomException()               { super()     }
   CustomException(String msg)         { super(msg) }
   CustomException(String msg, Throwable t) { super(msg, t) }
   CustomException(Throwable t)         { super(t)   }
}



                                                                36
@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    
    }
 }

                                                              37
@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    
       }
    }

                                                                 37
Miscelanous


• Compilation customizers
• Java 7 diamond operator
• Slashy and dollar slashy strings
• New GDK methods
• (G)String to Enum coercion



                                     38
Compilation customizers

• Ability to apply some customization to the Groovy
  compilation process

• Three available customizers
 –ImportCustomizer
 –ASTTransformationCustomizer
 –SecureASTCustomizer


• But you can implement your own
                                                 39
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 ")




                                                  40
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()
    """)


                                                    41
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()
                                                                        42
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'
 ...

                                                        43
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 ]
 }
 ...
                                                                    44
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)'


                                                       45
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 we're ${date}
          $ dollar-sign    
          $$ dollar-sign    
           backslash    
          / slash    
         $/ slash
       /$ 
                                                       46
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 }
                                                          47
(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

                                       48
Customizing the Groovysh prompt




                                  49
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 :-)

                                                         50
What’s
cooking
for 2.0?
Groovy 2.0 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!
                                         52
Groovy 2.0 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!
                                         52
Java 7 / JDK 7

• Project Coin and InvokeDynamic




                                   53
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
                                              54
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


                                                    55
Multicatch

• One block for multiple exception caught
 –rather than duplicating the block


   try {
      /* ... */
   } catch(IOException | NullPointerException e) {
      /* one block to treat 2 exceptions */
   }




                                                     56
InvokeDynamic
• Groovy 2.0 will support JDK 7’s
  invokeDynamic
 –an «indy» branch started recently
 –compiler will have a flag for compiling against JDK 7
 –might use the invokeDynamic backport


• 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            57
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.
                                                         58
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...
                                                  59
Typos in your variable or method

import groovy.transform.StaticTypes
 
void method() {}
 
@TypeChecked test() {
  // Cannot find matching method metthhoood()
  metthhoood()
 
  def name = "Guillaume"
  // variable naamme is undeclared
  println naamme
}



                                               60
Typos in your variable or method

import groovy.transform.StaticTypes
 
void method() {}
 
@TypeChecked test() {
  // Cannot find matching method metthhoood()
  metthhoood()
 
  def name = "Guillaume"                       Compilation
  // variable naamme is undeclared               errors!
  println naamme
}



                                                       60
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 = 0
i += '1'



                                                   61
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 = 0
i += '1'



                                                           61
Complain on wrong return types
 String method() { 'String' }
 // cannot assign value of type String...
 int x = method()

 // checks if/else branch return values
 int method() {
    if (true) { 'String' }
    else { 42 }
 }
 // works for switch/case & try/catch/finally
  
 // transparent toString() implied
 String greeting(String name) {
    def sb = new StringBuilder()
    sb << "Hi" << name
 }
                                               62
Complain on wrong return types
 String method() { 'String' }
 // cannot assign value of type String...
 int x = method()                              Compilation
                                               errors!
 // checks if/else branch return values
 int method() {
    if (true) { 'String' }
    else { 42 }
 }
 // works for switch/case & try/catch/finally
  
 // transparent toString() implied
 String greeting(String name) {
    def sb = new StringBuilder()
    sb << "Hi" << name
 }
                                                        62
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
     }
   }
                                                    63
Staticly checked & dyn. methods
     @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()
     }
                                               64
Bytecode viewer


• Groovy Console’s
  bytecode viewer
  from the AST
  browser window
 –select class
  generation phase
 –select a class node



                        65
Disable Global AST xforms
 // witout a specific configuration, the AST builder works
 def shell = new GroovyShell()
 shell.evaluate(script) // passes

 def 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 applied
 shell = new GroovyShell(config) // <-- with the configuration
 shouldFail {
     shell.evaluate(script) // fails
 }

                                                                    66
Summary




          ROCKS!
               67
Thank you!




                                e
                        aforg pment
              ume L Develo
      Guilla Groovy
              f
      Head o                        om
                        e@  gmail.c
               glaforg rge
       Email: @glafo                         e
                                    o/glaforg
       Tw  itter :        ://gplus.t pot.com
                   +: http rge.apps
        Google p://glafo
        B log: htt



                                                 68
Q&A
Got questions,
       really?
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

•




                                                                                                                            70

Más contenido relacionado

La actualidad más candente

Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 
Cacoo enterprise installation_manual
Cacoo enterprise installation_manualCacoo enterprise installation_manual
Cacoo enterprise installation_manualjoseig23
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Robert Treat
 
Athenticated smaba server config with open vpn
Athenticated smaba server  config with open vpnAthenticated smaba server  config with open vpn
Athenticated smaba server config with open vpnChanaka Lasantha
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
Ten common mistakes made in Function Java
Ten common mistakes made in Function JavaTen common mistakes made in Function Java
Ten common mistakes made in Function JavaBrian Vermeer
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitBrian Vermeer
 
Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Timote Lima
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomValeriy Kravchuk
 
Automate Your Application on the Cloud
Automate Your Application on the CloudAutomate Your Application on the Cloud
Automate Your Application on the Cloudtamirko
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automationLarry Nung
 
23769377 lab-bgp-juniper
23769377 lab-bgp-juniper23769377 lab-bgp-juniper
23769377 lab-bgp-junipercavang_3004
 
Fault Tolerance in a High Volume, Distributed System
Fault Tolerance in a  High Volume, Distributed SystemFault Tolerance in a  High Volume, Distributed System
Fault Tolerance in a High Volume, Distributed SystemBen Christensen
 
Watch Re-runs on your SQL Server with RML Utilities
Watch Re-runs on your SQL Server with RML UtilitiesWatch Re-runs on your SQL Server with RML Utilities
Watch Re-runs on your SQL Server with RML Utilitiesdpcobb
 

La actualidad más candente (20)

Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
 
Cacoo enterprise installation_manual
Cacoo enterprise installation_manualCacoo enterprise installation_manual
Cacoo enterprise installation_manual
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007
 
Advanced GAR
Advanced GARAdvanced GAR
Advanced GAR
 
Athenticated smaba server config with open vpn
Athenticated smaba server  config with open vpnAthenticated smaba server  config with open vpn
Athenticated smaba server config with open vpn
 
What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
Centos config
Centos configCentos config
Centos config
 
Ten common mistakes made in Function Java
Ten common mistakes made in Function JavaTen common mistakes made in Function Java
Ten common mistakes made in Function Java
 
Ten common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java SummitTen common mistakes made in Function Java - iSense Java Summit
Ten common mistakes made in Function Java - iSense Java Summit
 
Adb instructions
Adb instructionsAdb instructions
Adb instructions
 
Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)Xen server 6.0 xe command reference (1.1)
Xen server 6.0 xe command reference (1.1)
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
 
Automate Your Application on the Cloud
Automate Your Application on the CloudAutomate Your Application on the Cloud
Automate Your Application on the Cloud
 
Refcard en-a4
Refcard en-a4Refcard en-a4
Refcard en-a4
 
Hadoop completereference
Hadoop completereferenceHadoop completereference
Hadoop completereference
 
Ansible - simple it automation
Ansible - simple it automationAnsible - simple it automation
Ansible - simple it automation
 
23769377 lab-bgp-juniper
23769377 lab-bgp-juniper23769377 lab-bgp-juniper
23769377 lab-bgp-juniper
 
Fault Tolerance in a High Volume, Distributed System
Fault Tolerance in a  High Volume, Distributed SystemFault Tolerance in a  High Volume, Distributed System
Fault Tolerance in a High Volume, Distributed System
 
Watch Re-runs on your SQL Server with RML Utilities
Watch Re-runs on your SQL Server with RML UtilitiesWatch Re-runs on your SQL Server with RML Utilities
Watch Re-runs on your SQL Server with RML Utilities
 

Más de Guillaume Laforge

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Guillaume Laforge
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Guillaume Laforge
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Guillaume Laforge
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Guillaume Laforge
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovyGuillaume Laforge
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Guillaume Laforge
 
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Guillaume Laforge
 
Gaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGroovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGuillaume Laforge
 

Más de Guillaume Laforge (20)

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovy
 
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume LaforgeGroovy DSLs - S2GForum London 2011 - Guillaume Laforge
Groovy DSLs - S2GForum London 2011 - Guillaume Laforge
 
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
Gaelyk - Guillaume Laforge - GR8Conf Europe 2011
 
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
Groovy 1.8 update - Guillaume Laforge - GR8Conf Europe 2011
 
Gaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume LaforgeGaelyk - JFokus 2011 - Guillaume Laforge
Gaelyk - JFokus 2011 - Guillaume Laforge
 
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume LaforgeGroovy Ecosystem - JFokus 2011 - Guillaume Laforge
Groovy Ecosystem - JFokus 2011 - Guillaume Laforge
 
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume LaforgeGroovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
Groovy and Gaelyk - Lausanne JUG 2011 - Guillaume Laforge
 
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume LaforgeGaelyk - Paris GGUG 2011 - Guillaume Laforge
Gaelyk - Paris GGUG 2011 - Guillaume Laforge
 
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume LaforgeGaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
Gaelyk - Groovy Grails eXchange 2010 - Guillaume Laforge
 

Último

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphNeo4j
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 

Último (20)

[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge GraphSIEMENS: RAPUNZEL – A Tale About Knowledge Graph
SIEMENS: RAPUNZEL – A Tale About Knowledge Graph
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 

Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011

  • 1. What’s new in Groovy? Groovy 1.8 and what’s ahead Guillaume Laforge @glaforge Groovy Project Manager http://glaforge.appspot.com SpringSource / VMware http://gplus.to/glaforge
  • 2. Guillaume Laforge • Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge 2
  • 3. Agenda • What’s new in Groovy 1.8? –Nicer DSLs with command chains –Runtime performance improvements –GPars bundled for taming your multicores –Closure enhancements –Builtin JSON support –New AST transformations 3
  • 4. Agenda • What’s cooking for Groovy 2.0? –Alignments with JDK 7 • Project Coin (small language changes) • InvokeDynamic – Continued runtime performance improvements –Static type checking and compilation 4
  • 5. Command chains • A grammar improvement allowing you to drop dots & parens when chaining method calls –an extended version of top-level statements like println • Less dots, less parens allow you to –write more readable business rules –in almost plain English sentences • (or any language, of course) 5
  • 6. Command chains turn left then right 6
  • 7. Command chains Alternation of method names turn left then right 6
  • 8. Command chains Alternation of method names turn left then right and parameters (even named ones) 6
  • 9. Command chains turn left then right 6
  • 10. Command chains Equivalent to: turn left then) right ( ). ( 6
  • 11. LookM a! N op are ns, no do ts!
  • 12. Command chains Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours 8
  • 13. Command chains Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument 8
  • 14. Command chains Before... we used to do... take 2.pills, of: chloroquinine, after: 6.hours Normal argument Named arguments 8
  • 15. Command chains 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) 8
  • 16. Command chains Now, even less punctuation! take 2 pills of chloroquinine after 6 hours 9
  • 17. Command chains Now, even less punctuation! take).2 pills of chloroquinine ) ( ( ). ( ). ( after 6 hours 9
  • 18. Command chains // Java fluent API approach class RegimenBuilder { ... def take(int n) { this.pills = n return this } def pills(String of) { return this } ... } 10
  • 19. Command chains // 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 11
  • 21. Command chains // methods with multiple arguments (commas) 12
  • 22. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor 12
  • 23. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation 12
  • 24. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good 12
  • 25. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures 12
  • 26. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} 12
  • 27. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens 12
  • 28. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names 12
  • 29. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms 12
  • 30. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 12
  • 31. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  tastes good // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 12
  • 32. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given {}  when {}  then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 12
  • 33. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names // possible with an odd number of terms take 3  cookies 12
  • 34. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names ( ). . ( ) // possible with an odd number of terms take 3  cookies 12
  • 35. Command chains // methods with multiple arguments (commas) take coffee  with sugar, milk  and liquor ( ). ( ). ( ) // leverage named-args as punctuation check that: margarita  )tastes good ( ). ( // closure parameters for new control structures given). when {}  ) ( {}  ( ). ( then {} // zero-arg methods require parens select all  unique() from names ( ). . ( ) // possible with an odd number of terms take).3  cookies ( 12
  • 36. Runtime performance • Significant runtime improvements for primitive type operations –classical Fibonacci example x13 faster! –closer to Java performance • Some direct method calls on this 13
  • 37. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms –actors, fork/join, map/filter/reduce, dataflow, agents –parallel arrays, executors, STM, and more... 14
  • 38. Closure enhancements • Closure annotation parameters • Some more functional flavor –composition –trampoline –memoization • Currying improvements 15
  • 39. 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) 16
  • 40. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface Invariant {     Class value() // a closure class } {   @Invariant({ number >= 0 }) class Distance {     GCon tracts float number     oor-m an’s P 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) 16
  • 41. 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) 17
  • 43. 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... 18
  • 45. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() 19
  • 46. Closure memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms 19
  • 47. 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 19
  • 48. 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 19
  • 49. 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   19
  • 50. 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     19
  • 51. 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 19
  • 52. 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) 19
  • 53. 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)   19
  • 54. 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 19
  • 55. 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)  19
  • 56. 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 19
  • 57. 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) 19
  • 59. Currying improvements // right currying def divide = { a, b -> a / b } def halver = divide.rcurry(2) assert halver(8) == 4     20
  • 60. 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' 20
  • 61. Builtin JSON support • Consuming • Producing • Pretty-printing 21
  • 62. 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 } 22
  • 63. Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {     name "Guillaume" age 34     pets "Hector", "Felix" }  println json.toString() 23
  • 64. Builtin JSON support import groovy.json.*    def json = new JsonBuilder()    json.person {     {     name "Guillaume" "person": {         "name": "Guillaume",         age 34     "age": 34,         pets "Hector", "Felix" "pets": [             }  "Hector",             "Felix"         println json.toString() ]     } } 23
  • 65. Builtin JSON support import groovy.json.*    println JsonOutput.prettyPrint( '''{"person":{"name":"Guillaume","age":34,''' + '''"pets":["Hector","Felix"]}}''')   {     "person": {         "name": "Guillaume",         "age": 34,         "pets": [             "Hector",             "Felix"         ]     } } 24
  • 66. New AST transformations • @Log • @Canonical – @ToString, • @Field – @EqualsAndHashCode, – @TupleConstructor • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • Controlling the execution of your code • @WithWriteLock – @ThreadInterrupt, – @TimedInterrupt, • @ListenerList – @ConditionalInterrupt 25
  • 67. @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() 26
  • 68. @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() 26
  • 69. @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 27
  • 70. 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? 28
  • 71. 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 28
  • 72. 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 28
  • 73. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { // eat lots of CPU } 29 33
  • 74. @ThreadInterrupt @ThreadInterrupt import groovy.transform.ThreadInterrupt    while (true) { { if (Thread.currentThread.isInterrupted()) throw new InterruptedException() } // eat lots of CPU } 29 33
  • 75. @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) 29 33
  • 76. @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) 30
  • 77. @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...' } 31
  • 78. @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) 32
  • 79. @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() 33
  • 80. @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 34
  • 81. @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 35
  • 82. @InheritConstructors • Classes like Exception are painful when extended, as all the base constructors should be replicated class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) } } 36
  • 83. @InheritConstructors • Classes like Exception are painful when extended, as all the base constructors should be replicated import groovy.transform.* @InheritConstructors class CustomException extends Exception { CustomException() { super() } CustomException(String msg) { super(msg) } CustomException(String msg, Throwable t) { super(msg, t) } CustomException(Throwable t) { super(t) } } 36
  • 84. @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     } } 37
  • 85. @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     } } 37
  • 86. Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion 38
  • 87. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers –ImportCustomizer –ASTTransformationCustomizer –SecureASTCustomizer • But you can implement your own 39
  • 88. 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 ") 40
  • 89. 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() """) 41
  • 90. 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() 42
  • 91. 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' ... 43
  • 92. 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 ] } ... 44
  • 93. 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)' 45
  • 94. 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 we're ${date} $ dollar-sign     $$ dollar-sign     backslash     / slash     $/ slash /$  46
  • 95. 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 } 47
  • 96. (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 48
  • 98. 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 :-) 50
  • 100. Groovy 2.0 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! 52
  • 101. Groovy 2.0 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! 52
  • 102. Java 7 / JDK 7 • Project Coin and InvokeDynamic 53
  • 103. 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 54
  • 104. 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 55
  • 105. Multicatch • One block for multiple exception caught –rather than duplicating the block try { /* ... */ } catch(IOException | NullPointerException e) { /* one block to treat 2 exceptions */ } 56
  • 106. InvokeDynamic • Groovy 2.0 will support JDK 7’s invokeDynamic –an «indy» branch started recently –compiler will have a flag for compiling against JDK 7 –might use the invokeDynamic backport • 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 57
  • 107. 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. 58
  • 108. 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... 59
  • 109. Typos in your variable or method import groovy.transform.StaticTypes   void method() {}   @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood()   def name = "Guillaume" // variable naamme is undeclared println naamme } 60
  • 110. Typos in your variable or method import groovy.transform.StaticTypes   void method() {}   @TypeChecked test() { // Cannot find matching method metthhoood() metthhoood()   def name = "Guillaume" Compilation // variable naamme is undeclared errors! println naamme } 60
  • 111. 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 = 0 i += '1' 61
  • 112. 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 = 0 i += '1' 61
  • 113. Complain on wrong return types String method() { 'String' } // cannot assign value of type String... int x = method() // checks if/else branch return values int method() { if (true) { 'String' } else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied String greeting(String name) { def sb = new StringBuilder() sb << "Hi" << name } 62
  • 114. Complain on wrong return types String method() { 'String' } // cannot assign value of type String... int x = method() Compilation errors! // checks if/else branch return values int method() { if (true) { 'String' } else { 42 } } // works for switch/case & try/catch/finally   // transparent toString() implied String greeting(String name) { def sb = new StringBuilder() sb << "Hi" << name } 62
  • 115. 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 } } 63
  • 116. Staticly checked & dyn. methods @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() } 64
  • 117. Bytecode viewer • Groovy Console’s bytecode viewer from the AST browser window –select class generation phase –select a class node 65
  • 118. Disable Global AST xforms // witout a specific configuration, the AST builder works def shell = new GroovyShell() shell.evaluate(script) // passes def 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 applied shell = new GroovyShell(config) // <-- with the configuration shouldFail { shell.evaluate(script) // fails } 66
  • 119. Summary ROCKS! 67
  • 120. Thank you! e aforg pment ume L Develo Guilla Groovy f Head o om e@ gmail.c glaforg rge Email: @glafo e o/glaforg Tw itter : ://gplus.t pot.com +: http rge.apps Google p://glafo B log: htt 68
  • 121. Q&A Got questions, really?
  • 122. 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 • 70

Notas del editor

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n