SlideShare a Scribd company logo
1 of 120
Download to read offline
Groovy 2.0
What’s up doc?
  Guillaume Laforge
  Groovy Project Manager
        @glaforge




                           1
Groovy 2.0
What’s up doc?
  Guillaume Laforge
  Groovy Project Manager
        @glaforge




                           1
Guillaume Laforge
 •   Groovy Project Manager at VMware
     •Initiator of the Grails framework
     •Creator of the Gaelyk
      and Caelyf toolkits

 •   Co-author of Groovy in Action


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

 • 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 (2/2)

 • What’s cooking for Groovy 2.0?
  • Alignments with JDK 7
   • Project Coin (small language changes)
   • Invoke Dynamic support
    • Continued runtime performance improvements
  • Static type checking
  • Static compilation
  • Modularity
                                                   4
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



       !pull!request!!on!github!




                                   6
Command chains
         Alternation of
         method names




       !pull!request!!on!github!




                                   6
Command chains
         Alternation of
         method names




       !pull!request!!on!github!


                      and parameters
                    (even named ones)




                                        6
Command chains



       !pull!request!!on!github!




                                   6
Command chains


        Equivalent to:


       !pull!request!!on!github!
       !!!!!(!!!!!!!).!!(!!!!!!)




                                   6
Command chains



    commit!2!!changes!on!!master!!branch




                                           7
Command chains



    !!!!!!(!).!!!!!!!(!!).!!!!!!!(!!!!!!)
    commit!2!!changes!on!!master!!branch




                                            7
Command chains




                 8
Command chains
   //!methods!with!multiple!arguments!(commas)




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




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

   //!leverage!named>args!as!punctuation




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

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




                                                 8
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




                                                      8
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!{}




                                                      8
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




                                                      8
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




                                                      8
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




                                                      8
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



                                                      8
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



                                                      8
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



                                                      8
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



                                                      8
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



                                                      8
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
   !!!!(!).



                                                      8
GPars bundled

 •   GPars is bundled in the Groovy distribution


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


 •   And you can use it from plain Java as well!


                                                             9
Closure enhancements
 • Closure annotation parameters
 •    Some more functional flavor
     • composition
         •
         compose several closures into one single closure
     • trampoline
       • avoid stack overflow errors for recursive algorithms
     • memoization
       • remember the outcome of previous closure invocations
     • currying improvements

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


                                                         11
Closure annotation parameters
     @Retention(RetentionPolicy.RUNTIME)
     @interface!Invariant!{!!!!
     !!!!Class!value()!//!a!closure!class
     }
     !

 {   @Invariant({.number.>=.0.})
     class!Distance!{!!!!
     !!!!float!number!!!!
                                 Poor- man’s
                                             GCon tracts

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


                                                           11
Closure memoization




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




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

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




                                                        12
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




                                                        12
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




                                                        12
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!!




                                                        12
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!!
   !




                                                        12
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




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




                                                        12
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)
   !




                                                        12
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




                                                        12
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).




                                                        12
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



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


                                                        12
Builtin JSON support

  •   Consuming


  •   Producing


  •   Pretty-printing




                        13
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!}




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




                                15
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",!!!!!!!!
                                                        !
println!json.toString()     !!!!!!!!!!!!"Felix"!!!!!!!!
                              !!!!!!!!]!!!!
                              !!!!}
                              }



                                                       15
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"!!!!!!!!
                !!!!!!!!]!!!!
                !!!!}
                }


                                                             16
New AST transformations
• @Log                       • Controlling execution
                                 •   @ThreadInterrupt

•   @Field                       •   @TimedInterrupt
                                 •   @ConditionalInterrupt


•   @AutoClone
                             • @InheritConstructor
•   @AutoExternalizable

                             •   @WithReadLock
•   @Canonical
                             •   @WithWriteLock
    •   @ToString
    •   @EqualsAndHashCode
    •   @TupleConstructor    •   @ListenerList

                                                             17
@Log
•   Four different loggers can be injected
    •@Log
    •@Commons                   import!groovy.util.logging.*!
    •@Log4j                     !
                                @Log
    •@Slf4j                     class!Car!{!!!!
                               !!!!Car()!{!!!!!!!!
                               !!!!!!!!log.info!'Car!constructed'!
                                                                 !

•   Possible to implement      !!!!}
                               }!
    your own strategy          !
                               def!c!=!new!Car()




                                                                18
@Log
•   Four different loggers can be injected
    •@Log
    •@Commons                   import!groovy.util.logging.*!
    •@Log4j                     !
                                @Log
    •@Slf4j
                   Guarded
                   w/ an if
                                class!Car!{!!!!
                               !!!!Car()!{!!!!!!!!
                               !!!!!!!!log.info!'Car!constructed'!
                                                                 !

•   Possible to implement      !!!!}
                               }!
    your own strategy          !
                               def!c!=!new!Car()




                                                                18
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
                                                                 19
@ThreadInterrupt

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


     !!!!//!eat!lots!of!CPU
     }




                                                20


                                                     33
@ThreadInterrupt

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

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




                                                           20


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

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

                                                         22
@TupleConstructor
•   Provides a «classical» constructor with all properties
•   Several annotation parameter options available

             import!groovy.transform.TupleConstructor!
             !
             @TupleConstructor!
             class!Person!{!!!!
             !!!!String!name!!!!
             !!!!int!age
             }!
             !
             def!m!=!new!Person('Marion',!4)!!!!!!
             !
             assert!m.name!==!'Marion'
             assert!m.age!!==!4

                                                             23
@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)!!!!!!}
    }




                                                                     24
@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)!!!!!!}
    }




                                                                     24
Miscelanous
 •   Compilation customizers
 •   Java 7 diamond operator
 •   Slashy and dollar slashy strings
 •   New GDK methods
 •   (G)String to Enum coercion
 •   Customizing the Groovysh prompt
 •   Executing remote scripts




                                        25
Compilation customizers
 •   Ability to apply some customization to the Groovy
     compilation process


 •   Three available customizers
     •ImportCustomizer
     •ASTTransformationCustomizer
     •SecureASTCustomizer


 •   But you can implement your own


                                                         26
Imports customizer

   def!configuration!=!new!CompilerConfiguration()
   !
   def!custo!=!new!ImportCustomizer()
   custo.addStaticStar(Math.name)
   configuration.addCompilationCustomizers(custo)!
   !
   def!result!=!new!GroovyShell(configuration)
   !!!!!!!!!!!!!//!import!static!java.lang.Math.*
   !!!!.evaluate("!cos!PI/3!")
   !!!!!!!!!!!!!!




                                                     27
What’s
in store
for 2.0?
2.0


Around the corner...
Groovy 2.0
 •   A more modular Groovy
 •   Java 7 alignements: Project Coin
     • binary literals
     • underscore in literals
     • multicatch
 •   JDK 7: InvokeDynamic
 •   Static type checking
 •   Static compilation




                                        30
Groovy Modularity
 •   Groovy’s «all» JAR weighs in at 6 MB


 • Nobody needs everything
  • Template engine, Ant scripting, Swing UI building...
 •   Provide a smaller core
     •and several smaller JARs per feature


 •   Provide hooks for setting up DGM methods, etc.


                                                           31
The new JARs
 •   A smaller groovy.jar: 3MB


 •   Modules
     •console                    •   sql
     •docgenerator               •   swing
     •groovydoc                  •   servlet
     •groovysh                   •   templates
     •ant                        •   test
     •bsf                        •   testng
     •jsr-223                    •   json
     •jmx                        •   xml
                                                 32
Extension modules
 •   Create your own module
     •contribute instance extension methods

  package!foo

  class!StringExtension!{
  !!!!static.introduce(String!self,!String!name)!{
  !!!!!!!!"Hi!${name),!I’m!${self}"
  !!!!}
  }

  //!usage:!"Guillaume".introduce("Cédric")


                                                     33
Extension modules
 •   Create your own module
     •contribute instance extension methods   Same structure
                                               as Categories

  package!foo

  class!StringExtension!{
  !!!!static.introduce(String!self,!String!name)!{
  !!!!!!!!"Hi!${name),!I’m!${self}"
  !!!!}
  }

  //!usage:!"Guillaume".introduce("Cédric")


                                                           33
Extension modules
 •   Create your own module
     •contribute class extension methods

              package!foo

              class!StaticStringExtension!{
              !!!!static.hi(String!self)!{
              !!!!!!!!"Hi!"
              !!!!}
              }

              //!usage:!String.hi()


                                              34
Extension module descriptor


 moduleName!=!stringExtensions
 moduleVersion!=!1.0
 //!coma>separated!list!of!classes
 extensionClasses!=!foo.StringExtension
 //!coma>separated!list!of!classes
 staticExtensionClasses!=!foo.StaticStringExtension




                                                      35
Java 7 / JDK 7

  •   Project Coin and InvokeDynamic




                                       36
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


                                                          37
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



                                                         38
Multicatch
•   One block for multiple exception caught
    •rather than duplicating the block



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




                                                          39
InvokeDynamic
 • Groovy 2.0 supports JDK 7’s invokeDynamic
  • compiler has a flag for compiling against JDK 7
  • might use the invokeDynamic backport for < JDK 7
 •   Benefits
     • more runtime performance!
         •
        at least as fast as current «dynamic» Groovy
     •in the long run, will allow us to get rid of code!
         •
        call site caching, thanks to MethodHandles
         •
        metaclass registry, thanks to ClassValues
         •
        will let the JIT inline calls more easily
                                                           40
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...
                                                          41
Typos in a variable or method

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



                                                   42
Typos in a variable or method

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



                                                          42
Typos in a variable or method
                                         Annotation can be at
 import!groovy.transform.TypeChecked     class or method level
 !
 void!method()!{}
 !
 @TypeChecked!test()!{
 !!!!//!Cannot!find!matching!method!metthhoood()
 !!!!metthhoood()
 !
 !!!!def!name!=!"Guillaume"                 Compilation
 !!!!//!variable!naamme!is!undeclared         errors!
 !!!!println!naamme
 }



                                                             42
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'




                                                        43
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'




                                                                   43
Wrong return types
     //!checks!if/else!branch!return!values
     @TypeChecked
     int!method()!{
     !!!!if!(true)!{!'String'!}
     !!!!else!{!42!}
     }
     //!works!for!switch/case!&!try/catch/finally
     !
     //!transparent!toString()!implied
     @TypeChecked
     String!greeting(String!name)!{
     !!!!def!sb!=!new!StringBuilder()
     !!!!sb!<<!"Hi!"!<<!name
     }


                                                    44
Wrong return types
     //!checks!if/else!branch!return!values
     @TypeChecked
     int!method()!{                 Compilation
     !!!!if!(true)!{!'String'!}        error!
     !!!!else!{!42!}
     }
     //!works!for!switch/case!&!try/catch/finally
     !
     //!transparent!toString()!implied
     @TypeChecked
     String!greeting(String!name)!{
     !!!!def!sb!=!new!StringBuilder()
     !!!!sb!<<!"Hi!"!<<!name
     }


                                                    44
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
     !!!!}
     }

                                                        45
Statically checked & dyn. meth.
       @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()
       }

                                                  46
Instanceof checks
   @TypeChecked!
   void.test(Object!val)!{

   !!!!if!(val!instanceof.String)!{
   !!!!!!!!println!val.toUpperCase()
   !!!!}!else.if!(val!instanceof.Number)!{
   !!!!!!!!println!"X"!*!val.intValue()
   !!!!}

   }




                                             47
Instanceof checks
                                             No need
   @TypeChecked!
                                             for casts
   void.test(Object!val)!{

   !!!!if!(val!instanceof.String)!{
   !!!!!!!!println!val.toUpperCase()
   !!!!}!else.if!(val!instanceof.Number)!{
   !!!!!!!!println!"X"!*!val.intValue()
   !!!!}

   }




                                                     47
Instanceof checks
                                              No need
    @TypeChecked!
                                              for casts
    void.test(Object!val)!{

    !!!!if!(val!instanceof.String)!{
    !!!!!!!!println!val.toUpperCase()
    !!!!}!else.if!(val!instanceof.Number)!{
    !!!!!!!!println!"X"!*!val.intValue()
    !!!!}

    }


    Can call String#multiply(int)
   from the Groovy Development Kit

                                                      47
Lowest Upper Bound
 •   Represents the lowest «super» type classes
     have in common
     •may be virtual (aka «non-denotable»)


           @TypeChecked!test()!{
           !!!!//!an!integer!and!a!BigDecimal
           !!!!return![1234,!3.14]
           }




                                                  48
Lowest Upper Bound
 •   Represents the lowest «super» type classes
     have in common
     •may be virtual (aka «non-denotable»)


           @TypeChecked!test()!{
           !!!!//!an!integer!and!a!BigDecimal
           !!!!return![1234,!3.14]
           }


                         Inferred return type:
                     List<Number & Comparable>
                                                  48
Lowest Upper Bound
 •   Represents the lowest «super» type classes
     have in common
     •may be virtual (aka «non-denotable»)


           @TypeChecked!test()!{
           !!!!//!an!integer!and!a!BigDecimal
           !!!!return![1234,!3.14]
           }


                         Inferred return type:
                     List<Number & Comparable>
                                                  48
Flow typing
 •   Static type checking shouldn’t complain even for bad coding
     practicies which work without type checks


     @TypeChecked!test()!{
     !!!!def!var!=!123!!!!!!!!!//!inferred!type!is!int
     !!!!int.x!=!var!!!!!!!!!!!//!var!is!an!int
     !!!!var!=!"123"!!!!!!!!!!!//!assign!var!with!a!String

     !!!!x!=!var.toInteger()!!!//!no!problem,!no!need!to!cast

     !!!!var!=!123
     !!!!x!=!var.toUpperCase()!//!error,!var!is!int!
     }



                                                                49
Gotcha: static checking vs dynamic
  •   Type checking works at compile-time
      •adding @TypeChecked doesn’t change behavior
          •
         do not confuse with static compilation


  •   Most dynamic features cannot be type checked
      •metaclass changes, categories
      •dynamically bound variables (ex: script’s binding)


  •   However, compile-time metaprogramming works
      •as long as proper type information is defined

                                                            50
Gotcha: runtime metaprogramming

      @TypeChecked!
      void.test()!{
      !!!!Integer.metaClass.foo!=!{}
      !!!!123.foo()
      }




                                       51
Gotcha: runtime metaprogramming

      @TypeChecked!
      void.test()!{
      !!!!Integer.metaClass.foo!=!{}
      !!!!123.foo()
      }



                        Not allowed:
                     metaClass property
                        is dynamic


                                          51
Gotcha: runtime metaprogramming

      @TypeChecked!
      void.test()!{
      !!!!Integer.metaClass.foo!=!{}
      !!!!123.foo()
      }



        Method not      Not allowed:
        recognized   metaClass property
                        is dynamic


                                          51
Gotcha: explicit type for closures
  @TypeChecked!test()!{
  !!!!["a",!"b",!"c"].collect!{
  !!!!!!!!it.toUpperCase()!//!Not!OK
  !!!!}
  }



  •   A « Groovy Enhancement Proposal » to address the issue




                                                               52
Gotcha: explicit type for closures
  @TypeChecked!test()!{
  !!!!["a",!"b",!"c"].collect!{!String!it!>>
  !!!!!!!!it.toUpperCase()!//!OK,!it’s!a!String
  !!!!}
  }



  •   A « Groovy Enhancement Proposal » to address the issue




                                                               52
Closure shared variables

        @TypeChecked!test()!{
        !!!!def!var!=!"abc"!!!!!!!
        !!!!def!cl!=!{!var!=!new!Date()!}
        !!!!cl()
        !!!!var.toUpperCase()!!//!Not!OK!
        }




                                            53
Closure shared variables
                           var assigned in the closure:
                            «shared closure variable»

        @TypeChecked!test()!{
        !!!!def!var!=!"abc"!!!!!!!
        !!!!def!cl!=!{!var!=!new!Date()!}
        !!!!cl()
        !!!!var.toUpperCase()!!//!Not!OK!
        }




                                                          53
Closure shared variables
                                    var assigned in the closure:
                                     «shared closure variable»

                 @TypeChecked!test()!{
 Impossible to
                 !!!!def!var!=!"abc"!!!!!!!
  ensure the
                 !!!!def!cl!=!{!var!=!new!Date()!}
 assignment
                 !!!!cl()
really happens
                 !!!!var.toUpperCase()!!//!Not!OK!
                 }




                                                                   53
Closure shared variables
                                          var assigned in the closure:
                                           «shared closure variable»

                 @TypeChecked!test()!{
 Impossible to
                 !!!!def!var!=!"abc"!!!!!!!
  ensure the
                 !!!!def!cl!=!{!var!=!new!Date()!}
 assignment
                 !!!!cl()
really happens
                 !!!!var.toUpperCase()!!//!Not!OK!
                 }



                  Only methods of the most specific
                     compatible type (LUB) are
                    allowed by the type checker

                                                                         53
Closure shared variables
       class!A!!!!!!!!!!!{!void.foo()!{}!}
       class!B!extends!A!{!void.bar()!{}!}

       @TypeChecked!test()!{
       !!!!def!var!=!new!A()
       !!!!def!cl!=!{!var!=!new!B()!}
       !!!!cl()
       !!!!var.foo()!!!//!OK!
       }




                                             54
Closure shared variables
       class!A!!!!!!!!!!!{!void.foo()!{}!}
       class!B!extends!A!{!void.bar()!{}!}

       @TypeChecked!test()!{
       !!!!def!var!=!new!A()
       !!!!def!cl!=!{!var!=!new!B()!}
       !!!!cl()
       !!!!var.foo()!!!//!OK!
       }



          var is at least
         an instance of A

                                             54
Static Compilation

  •   Given your Groovy code can be type checked...
      we can as well compile it «statically»


      •   ie. generate the same byte code as javac


  •   Also interesting for those stuck in JDK < 7
      to benefit from performance improvements




                                                      55
Static Compilation: advantages
  •    You gain:


      • Type safety
       • thanks to static type checking
        • static compilation builds upon static type checking
      • Faster code
       • as close as possible to Java’s performance
      • Code immune to «monkey patching»
       • metaprogramming badly used can interfere with
           framework code
      •   Smaller bytecode size
                                                                56
Static Compilation: disadvantages
  •   But you loose:


      •   Dynamic features
          •metaclass changes, categories, etc.


      •   Dynamic method dispatch
          •although as close as possible to «dynamic» Groovy




                                                               57
Statically compiled & dyn methods
       @CompileStatic
       String!greeting(String!name)!{
       !!!!//!call!method!with!dynamic!behavior
       !!!!//!but!with!proper!signature
       !!!!generateMarkup(name.toUpperCase())
       }
       !
       //!usual!dynamic!behavior
       String!generateMarkup(String!name)!{
       !!!!def!sw!=!new!StringWriter()
       !!!!new!MarkupBuilder(sw).html!{
       !!!!!!!!body!{
       !!!!!!!!!!!!div!name
       !!!!!!!!}
       !!!!}
       !!!!sw.toString()
       }

                                                  58
What about performance?
 •   Comparisons between:


     •   Java


     •   Groovy static compilation (Groovy 2.0)
     •   Groovy with primitive optimizations (Groovy 1.8+)
     •   Groovy without optimizations (Groovy 1.7)




                                                        59
What about performance?
                                            Pi (π)     Binary
                              Fibonacci
                                          quadrature   trees

                  Java        188 ms        97 ms      3.6 s

                Static
1.7 1.8 2.0




              compilation
                              202 ms      101 ms       4.4 s

                Primitive
              optimizations
                              360 ms       111 ms      23.7 s

                No prim.
              optimizations
                              2590 ms     3220 ms      50.0 s


                                                                60
Summary
 •   Main themes of the Groovy 2.0 release
     •Modularity


     •   Embark the JDK 7 enhancements
         •Project Coin
         •Invoke Dynamic


     •   Static aspects
         • Static type checking
         • Static compilation

                                             61
62
Thank you!



                             ge
                      e Lafor lopment
         Gu illaum ovy Deve
                   Gro
         H ead of
                                    om
                        ge@ gmail.c
          Emai l: glafor forge               e
                    :@  gla       .to/glaforg
          Twitter : http://gplus spot.com
                     +             pp
           Google p://glaforge.a
                    tt
            Blog: h




                                                 63
Questions & Answers
 •   Got questions, really?


                              Q&A




                                    64
Image credits
 •   Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg

 •   Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg

 •   Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg

 •   Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg

 •   Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg

 •   Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg

 •   Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg

 •   Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg

 •   Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg

 •   Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg

 •   Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg

 •   Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg

 •   Around the corner: http://3.bp.blogspot.com/-wvfO5NUbi8Q/TzBqTh4SOsI/AAAAAAAADOg/lRE9XVHGiOc/s1600/around-the-corner_large.jpg

 •   Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg




                                                                                                                                      65

More Related Content

What's hot

Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Guillaume Laforge
 
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
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Guillaume Laforge
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Robert Treat
 
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 - 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
 
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
 
Spring into rails
Spring into railsSpring into rails
Spring into railsHiro Asari
 
Intro to Testing in Zope, Plone
Intro to Testing in Zope, PloneIntro to Testing in Zope, Plone
Intro to Testing in Zope, PloneQuintagroup
 
Hardening Drupal setup
Hardening Drupal setupHardening Drupal setup
Hardening Drupal setupZeeland Family
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjugBrian Vermeer
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Brian Vermeer
 
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)mahesh madushanka
 
Stack Smashing Protector (Paul Rascagneres)
Stack Smashing Protector (Paul Rascagneres)Stack Smashing Protector (Paul Rascagneres)
Stack Smashing Protector (Paul Rascagneres)Hackfest Communication
 
Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Brian Vermeer
 
Puppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLabPuppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLabAlessandro Franceschi
 
Orchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorOrchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorRaphaël PINSON
 

What's hot (20)

Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
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
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007Intro to pl/PHP Oscon2007
Intro to pl/PHP Oscon2007
 
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
 
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
 
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
 
Spring into rails
Spring into railsSpring into rails
Spring into rails
 
Intro to Testing in Zope, Plone
Intro to Testing in Zope, PloneIntro to Testing in Zope, Plone
Intro to Testing in Zope, Plone
 
Advanced GAR
Advanced GARAdvanced GAR
Advanced GAR
 
Hardening Drupal setup
Hardening Drupal setupHardening Drupal setup
Hardening Drupal setup
 
Centos config
Centos configCentos config
Centos config
 
Common mistakes functional java vjug
Common mistakes functional java vjugCommon mistakes functional java vjug
Common mistakes functional java vjug
 
Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018Common mistakes functional java | Oracle Code One 2018
Common mistakes functional java | Oracle Code One 2018
 
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)
Real Time Analytics - Stream Processing (Colombo big data meetup 18/05/2017)
 
Stack Smashing Protector (Paul Rascagneres)
Stack Smashing Protector (Paul Rascagneres)Stack Smashing Protector (Paul Rascagneres)
Stack Smashing Protector (Paul Rascagneres)
 
Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18Ten common mistakes made with Functional Java JBCNConf18
Ten common mistakes made with Functional Java JBCNConf18
 
JRuby and You
JRuby and YouJRuby and You
JRuby and You
 
Puppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLabPuppet Continuous Integration with PE and GitLab
Puppet Continuous Integration with PE and GitLab
 
Orchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and MspectatorOrchestrated Functional Testing with Puppet-spec and Mspectator
Orchestrated Functional Testing with Puppet-spec and Mspectator
 

Similar to Groovy 1.8 and 2.0 at GR8Conf Europe 2012

Javascript patterns
Javascript patternsJavascript patterns
Javascript patternsChandan Jog
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!Gautam Rege
 
A DevOps Perspective: MongoDB & MMF
A DevOps Perspective: MongoDB & MMFA DevOps Perspective: MongoDB & MMF
A DevOps Perspective: MongoDB & MMFMapMyFitness
 
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"Yandex
 
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...Nicolas Bettenburg
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to GoCloudflare
 
ICPSR - Complex Systems Computing - Session 7 - 2012
ICPSR - Complex Systems Computing - Session 7 - 2012ICPSR - Complex Systems Computing - Session 7 - 2012
ICPSR - Complex Systems Computing - Session 7 - 2012Daniel Katz
 
Testable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and DockerTestable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and DockerMandi Walls
 
Rackspace Cloud Monitoring - Strata NYC
Rackspace Cloud Monitoring - Strata NYCRackspace Cloud Monitoring - Strata NYC
Rackspace Cloud Monitoring - Strata NYCgdusbabek
 
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...Innovecs
 
Moving to modules
Moving to modulesMoving to modules
Moving to modulesSean Mize
 
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQAlvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQTanya Denisyuk
 
Behavior Driven Development, Ruby Style
Behavior Driven Development, Ruby StyleBehavior Driven Development, Ruby Style
Behavior Driven Development, Ruby StyleBozhidar Batsov
 
Beginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccKazuhiro Sera
 
Chaione Ember.js Training
Chaione Ember.js TrainingChaione Ember.js Training
Chaione Ember.js Trainingaortbals
 
PowerDNS Webinar - Part 2
PowerDNS Webinar - Part 2PowerDNS Webinar - Part 2
PowerDNS Webinar - Part 2Men and Mice
 
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?NETWAYS
 

Similar to Groovy 1.8 and 2.0 at GR8Conf Europe 2012 (20)

Javascript patterns
Javascript patternsJavascript patterns
Javascript patterns
 
RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!RubyConf Portugal 2014 - Why ruby must go!
RubyConf Portugal 2014 - Why ruby must go!
 
A DevOps Perspective: MongoDB & MMF
A DevOps Perspective: MongoDB & MMFA DevOps Perspective: MongoDB & MMF
A DevOps Perspective: MongoDB & MMF
 
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"
Дмитрий Щадей "Что помогает нам писать качественный JavaScript-код?"
 
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...
An Empirical Study on the Risks of Using Off-the-Shelf Techniques for Process...
 
An Introduction to Go
An Introduction to GoAn Introduction to Go
An Introduction to Go
 
ICPSR - Complex Systems Computing - Session 7 - 2012
ICPSR - Complex Systems Computing - Session 7 - 2012ICPSR - Complex Systems Computing - Session 7 - 2012
ICPSR - Complex Systems Computing - Session 7 - 2012
 
Testable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and DockerTestable Infrastructure with Chef, Test Kitchen, and Docker
Testable Infrastructure with Chef, Test Kitchen, and Docker
 
Rackspace Cloud Monitoring - Strata NYC
Rackspace Cloud Monitoring - Strata NYCRackspace Cloud Monitoring - Strata NYC
Rackspace Cloud Monitoring - Strata NYC
 
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
Reliable Python REST API (by Volodymyr Hotsyk) - Web Back-End Tech Hangout - ...
 
Brasil Ross 2011
Brasil Ross 2011Brasil Ross 2011
Brasil Ross 2011
 
Moving to modules
Moving to modulesMoving to modules
Moving to modules
 
Perfect Code
Perfect CodePerfect Code
Perfect Code
 
Transforming WebSockets
Transforming WebSocketsTransforming WebSockets
Transforming WebSockets
 
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQAlvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
Alvaro Videla, Building a Distributed Data Ingestion System with RabbitMQ
 
Behavior Driven Development, Ruby Style
Behavior Driven Development, Ruby StyleBehavior Driven Development, Ruby Style
Behavior Driven Development, Ruby Style
 
Beginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_cccBeginning Scala with Skinny Framework #jjug_ccc
Beginning Scala with Skinny Framework #jjug_ccc
 
Chaione Ember.js Training
Chaione Ember.js TrainingChaione Ember.js Training
Chaione Ember.js Training
 
PowerDNS Webinar - Part 2
PowerDNS Webinar - Part 2PowerDNS Webinar - Part 2
PowerDNS Webinar - Part 2
 
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
Puppet Camp Duesseldorf 2014: Martin Alfke - Can you upgrade to puppet 4.x?
 

More from 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
 
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
 

More from Guillaume Laforge (19)

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
 
Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
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
 
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
 

Recently uploaded

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentMahmoud Rabie
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...itnewsafrica
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...itnewsafrica
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesBernd Ruecker
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Karmanjay Verma
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 

Recently uploaded (20)

Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Digital Tools & AI in Career Development
Digital Tools & AI in Career DevelopmentDigital Tools & AI in Career Development
Digital Tools & AI in Career Development
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...Abdul Kader Baba- Managing Cybersecurity Risks  and Compliance Requirements i...
Abdul Kader Baba- Managing Cybersecurity Risks and Compliance Requirements i...
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
QCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architecturesQCon London: Mastering long-running processes in modern architectures
QCon London: Mastering long-running processes in modern architectures
 
Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#Microservices, Docker deploy and Microservices source code in C#
Microservices, Docker deploy and Microservices source code in C#
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 

Groovy 1.8 and 2.0 at GR8Conf Europe 2012

  • 1. Groovy 2.0 What’s up doc? Guillaume Laforge Groovy Project Manager @glaforge 1
  • 2. Groovy 2.0 What’s up doc? Guillaume Laforge Groovy Project Manager @glaforge 1
  • 3. Guillaume Laforge • Groovy Project Manager at VMware •Initiator of the Grails framework •Creator of the Gaelyk and Caelyf toolkits • Co-author of Groovy in Action • Follow me on... •My blog: http://glaforge.appspot.com •Twitter: @glaforge •Google+: http://gplus.to/glaforge 2
  • 4. Agenda (1/2) • 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
  • 5. Agenda (2/2) • What’s cooking for Groovy 2.0? • Alignments with JDK 7 • Project Coin (small language changes) • Invoke Dynamic support • Continued runtime performance improvements • Static type checking • Static compilation • Modularity 4
  • 6. 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
  • 7. Command chains !pull!request!!on!github! 6
  • 8. Command chains Alternation of method names !pull!request!!on!github! 6
  • 9. Command chains Alternation of method names !pull!request!!on!github! and parameters (even named ones) 6
  • 10. Command chains !pull!request!!on!github! 6
  • 11. Command chains Equivalent to: !pull!request!!on!github! !!!!!(!!!!!!!).!!(!!!!!!) 6
  • 12. Command chains commit!2!!changes!on!!master!!branch 7
  • 13. Command chains !!!!!!(!).!!!!!!!(!!).!!!!!!!(!!!!!!) commit!2!!changes!on!!master!!branch 7
  • 15. Command chains //!methods!with!multiple!arguments!(commas) 8
  • 16. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor 8
  • 17. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation 8
  • 18. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good 8
  • 19. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures 8
  • 20. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} 8
  • 21. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens 8
  • 22. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens select!all!!unique()!from!names 8
  • 23. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens select!all!!unique()!from!names //!possible!with!an!odd!number!of!terms 8
  • 24. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens select!all!!unique()!from!names //!possible!with!an!odd!number!of!terms take!3!!cookies 8
  • 25. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor !!!!(!!!!!!).!!!!(!!!!!!!!!!!).!!!(!!!!!!) //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens select!all!!unique()!from!names //!possible!with!an!odd!number!of!terms take!3!!cookies 8
  • 26. Command chains //!methods!with!multiple!arguments!(commas) take!coffee!!with!sugar,!milk!!and!liquor !!!!(!!!!!!).!!!!(!!!!!!!!!!!).!!!(!!!!!!) //!leverage!named>args!as!punctuation check!that:!margarita!!tastes!good !!!!!(!!!!!!!!!!!!!!!).!!!!!!(!!!!) //!closure!parameters!for!new!control!structures given!{}!!when!{}!!then!{} //!zero>arg!methods!require!parens select!all!!unique()!from!names //!possible!with!an!odd!number!of!terms take!3!!cookies 8
  • 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 select!all!!unique()!from!names //!possible!with!an!odd!number!of!terms take!3!!cookies 8
  • 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 !!!!!!(!!!).!!!!!!!!.!!!!(!!!!!) //!possible!with!an!odd!number!of!terms take!3!!cookies 8
  • 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 take!3!!cookies !!!!(!). 8
  • 30. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms •actors, fork/join, map/filter/reduce, dataflow, agents •parallel arrays, executors, STM, and more... • And you can use it from plain Java as well! 9
  • 31. Closure enhancements • Closure annotation parameters • Some more functional flavor • composition • compose several closures into one single closure • trampoline • avoid stack overflow errors for recursive algorithms • memoization • remember the outcome of previous closure invocations • currying improvements 10
  • 32. 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) 11
  • 33. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface!Invariant!{!!!! !!!!Class!value()!//!a!closure!class } ! { @Invariant({.number.>=.0.}) class!Distance!{!!!! !!!!float!number!!!! Poor- man’s GCon tracts !!!!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) 11
  • 35. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() 12
  • 36. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms 12
  • 37. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately 12
  • 38. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms 12
  • 39. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! 12
  • 40. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! ! 12
  • 41. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! ! //!at!least!10!invocations!cached 12
  • 42. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! ! //!at!least!10!invocations!cached def!plusAtLeast!=!{!...!}.memoizeAtLeast(10) 12
  • 43. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! ! //!at!least!10!invocations!cached def!plusAtLeast!=!{!...!}.memoizeAtLeast(10) ! 12
  • 44. Closure memoization def!plus!=!{!a,!b!>>!sleep!1000;!a!+!b!}.memoize() assert!plus(1,!2)!==!3!//!after!1000ms assert!plus(1,!2)!==!3!//!return!immediately assert!plus(2,!2)!==!4!//!after!1000ms assert!plus(2,!2)!==!4!//!return!immediately!! ! //!at!least!10!invocations!cached def!plusAtLeast!=!{!...!}.memoizeAtLeast(10) ! //!at!most!10!invocations!cached 12
  • 45. 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). 12
  • 46. 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 12
  • 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 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) 12
  • 48. Builtin JSON support • Consuming • Producing • Pretty-printing 13
  • 49. 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!} 14
  • 51. 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",!!!!!!!! ! println!json.toString() !!!!!!!!!!!!"Felix"!!!!!!!! !!!!!!!!]!!!! !!!!} } 15
  • 52. 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"!!!!!!!! !!!!!!!!]!!!! !!!!} } 16
  • 53. New AST transformations • @Log • Controlling execution • @ThreadInterrupt • @Field • @TimedInterrupt • @ConditionalInterrupt • @AutoClone • @InheritConstructor • @AutoExternalizable • @WithReadLock • @Canonical • @WithWriteLock • @ToString • @EqualsAndHashCode • @TupleConstructor • @ListenerList 17
  • 54. @Log • Four different loggers can be injected •@Log •@Commons import!groovy.util.logging.*! •@Log4j ! @Log •@Slf4j class!Car!{!!!! !!!!Car()!{!!!!!!!! !!!!!!!!log.info!'Car!constructed'! ! • Possible to implement !!!!} }! your own strategy ! def!c!=!new!Car() 18
  • 55. @Log • Four different loggers can be injected •@Log •@Commons import!groovy.util.logging.*! •@Log4j ! @Log •@Slf4j Guarded w/ an if class!Car!{!!!! !!!!Car()!{!!!!!!!! !!!!!!!!log.info!'Car!constructed'! ! • Possible to implement !!!!} }! your own strategy ! def!c!=!new!Car() 18
  • 56. 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 19
  • 57. @ThreadInterrupt @ThreadInterrupt import!groovy.transform.ThreadInterrupt! ! while!(true)!{ !!!!//!eat!lots!of!CPU } 20 33
  • 58. @ThreadInterrupt @ThreadInterrupt import!groovy.transform.ThreadInterrupt! ! while!(true)!{ { !!!!if!(Thread.currentThread.isInterrupted()) !!!!!!!!throw.new!InterruptedException() } !!!!//!eat!lots!of!CPU } 20 33
  • 59. @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) 21
  • 60. @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() 22
  • 61. @TupleConstructor • Provides a «classical» constructor with all properties • Several annotation parameter options available import!groovy.transform.TupleConstructor! ! @TupleConstructor! class!Person!{!!!! !!!!String!name!!!! !!!!int!age }! ! def!m!=!new!Person('Marion',!4)!!!!!! ! assert!m.name!==!'Marion' assert!m.age!!==!4 23
  • 62. @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)!!!!!!} } 24
  • 63. @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)!!!!!!} } 24
  • 64. Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion • Customizing the Groovysh prompt • Executing remote scripts 25
  • 65. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers •ImportCustomizer •ASTTransformationCustomizer •SecureASTCustomizer • But you can implement your own 26
  • 66. Imports customizer def!configuration!=!new!CompilerConfiguration() ! def!custo!=!new!ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)! ! def!result!=!new!GroovyShell(configuration) !!!!!!!!!!!!!//!import!static!java.lang.Math.* !!!!.evaluate("!cos!PI/3!") !!!!!!!!!!!!!! 27
  • 69. Groovy 2.0 • A more modular Groovy • Java 7 alignements: Project Coin • binary literals • underscore in literals • multicatch • JDK 7: InvokeDynamic • Static type checking • Static compilation 30
  • 70. Groovy Modularity • Groovy’s «all» JAR weighs in at 6 MB • Nobody needs everything • Template engine, Ant scripting, Swing UI building... • Provide a smaller core •and several smaller JARs per feature • Provide hooks for setting up DGM methods, etc. 31
  • 71. The new JARs • A smaller groovy.jar: 3MB • Modules •console • sql •docgenerator • swing •groovydoc • servlet •groovysh • templates •ant • test •bsf • testng •jsr-223 • json •jmx • xml 32
  • 72. Extension modules • Create your own module •contribute instance extension methods package!foo class!StringExtension!{ !!!!static.introduce(String!self,!String!name)!{ !!!!!!!!"Hi!${name),!I’m!${self}" !!!!} } //!usage:!"Guillaume".introduce("Cédric") 33
  • 73. Extension modules • Create your own module •contribute instance extension methods Same structure as Categories package!foo class!StringExtension!{ !!!!static.introduce(String!self,!String!name)!{ !!!!!!!!"Hi!${name),!I’m!${self}" !!!!} } //!usage:!"Guillaume".introduce("Cédric") 33
  • 74. Extension modules • Create your own module •contribute class extension methods package!foo class!StaticStringExtension!{ !!!!static.hi(String!self)!{ !!!!!!!!"Hi!" !!!!} } //!usage:!String.hi() 34
  • 75. Extension module descriptor moduleName!=!stringExtensions moduleVersion!=!1.0 //!coma>separated!list!of!classes extensionClasses!=!foo.StringExtension //!coma>separated!list!of!classes staticExtensionClasses!=!foo.StaticStringExtension 35
  • 76. Java 7 / JDK 7 • Project Coin and InvokeDynamic 36
  • 77. 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 37
  • 78. 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 38
  • 79. Multicatch • One block for multiple exception caught •rather than duplicating the block try!{ !!!!/*!...!*/ }!catch(IOException!|!NullPointerException!e)!{ !!!!/*!one!block!to!treat!2!exceptions!*/ } 39
  • 80. InvokeDynamic • Groovy 2.0 supports JDK 7’s invokeDynamic • compiler has a flag for compiling against JDK 7 • might use the invokeDynamic backport for < JDK 7 • Benefits • more runtime performance! • at least as fast as current «dynamic» Groovy •in the long run, will allow us to get rid of code! • call site caching, thanks to MethodHandles • metaclass registry, thanks to ClassValues • will let the JIT inline calls more easily 40
  • 81. 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... 41
  • 82. Typos in a variable or method import!groovy.transform.TypeChecked ! void!method()!{} ! @TypeChecked!test()!{ !!!!//!Cannot!find!matching!method!metthhoood() !!!!metthhoood() ! !!!!def!name!=!"Guillaume" !!!!//!variable!naamme!is!undeclared !!!!println!naamme } 42
  • 83. Typos in a variable or method import!groovy.transform.TypeChecked ! void!method()!{} ! @TypeChecked!test()!{ !!!!//!Cannot!find!matching!method!metthhoood() !!!!metthhoood() ! !!!!def!name!=!"Guillaume" Compilation !!!!//!variable!naamme!is!undeclared errors! !!!!println!naamme } 42
  • 84. Typos in a variable or method Annotation can be at import!groovy.transform.TypeChecked class or method level ! void!method()!{} ! @TypeChecked!test()!{ !!!!//!Cannot!find!matching!method!metthhoood() !!!!metthhoood() ! !!!!def!name!=!"Guillaume" Compilation !!!!//!variable!naamme!is!undeclared errors! !!!!println!naamme } 42
  • 85. 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' 43
  • 86. 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' 43
  • 87. Wrong return types //!checks!if/else!branch!return!values @TypeChecked int!method()!{ !!!!if!(true)!{!'String'!} !!!!else!{!42!} } //!works!for!switch/case!&!try/catch/finally ! //!transparent!toString()!implied @TypeChecked String!greeting(String!name)!{ !!!!def!sb!=!new!StringBuilder() !!!!sb!<<!"Hi!"!<<!name } 44
  • 88. Wrong return types //!checks!if/else!branch!return!values @TypeChecked int!method()!{ Compilation !!!!if!(true)!{!'String'!} error! !!!!else!{!42!} } //!works!for!switch/case!&!try/catch/finally ! //!transparent!toString()!implied @TypeChecked String!greeting(String!name)!{ !!!!def!sb!=!new!StringBuilder() !!!!sb!<<!"Hi!"!<<!name } 44
  • 89. 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 !!!!} } 45
  • 90. Statically checked & dyn. meth. @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() } 46
  • 91. Instanceof checks @TypeChecked! void.test(Object!val)!{ !!!!if!(val!instanceof.String)!{ !!!!!!!!println!val.toUpperCase() !!!!}!else.if!(val!instanceof.Number)!{ !!!!!!!!println!"X"!*!val.intValue() !!!!} } 47
  • 92. Instanceof checks No need @TypeChecked! for casts void.test(Object!val)!{ !!!!if!(val!instanceof.String)!{ !!!!!!!!println!val.toUpperCase() !!!!}!else.if!(val!instanceof.Number)!{ !!!!!!!!println!"X"!*!val.intValue() !!!!} } 47
  • 93. Instanceof checks No need @TypeChecked! for casts void.test(Object!val)!{ !!!!if!(val!instanceof.String)!{ !!!!!!!!println!val.toUpperCase() !!!!}!else.if!(val!instanceof.Number)!{ !!!!!!!!println!"X"!*!val.intValue() !!!!} } Can call String#multiply(int) from the Groovy Development Kit 47
  • 94. Lowest Upper Bound • Represents the lowest «super» type classes have in common •may be virtual (aka «non-denotable») @TypeChecked!test()!{ !!!!//!an!integer!and!a!BigDecimal !!!!return![1234,!3.14] } 48
  • 95. Lowest Upper Bound • Represents the lowest «super» type classes have in common •may be virtual (aka «non-denotable») @TypeChecked!test()!{ !!!!//!an!integer!and!a!BigDecimal !!!!return![1234,!3.14] } Inferred return type: List<Number & Comparable> 48
  • 96. Lowest Upper Bound • Represents the lowest «super» type classes have in common •may be virtual (aka «non-denotable») @TypeChecked!test()!{ !!!!//!an!integer!and!a!BigDecimal !!!!return![1234,!3.14] } Inferred return type: List<Number & Comparable> 48
  • 97. Flow typing • Static type checking shouldn’t complain even for bad coding practicies which work without type checks @TypeChecked!test()!{ !!!!def!var!=!123!!!!!!!!!//!inferred!type!is!int !!!!int.x!=!var!!!!!!!!!!!//!var!is!an!int !!!!var!=!"123"!!!!!!!!!!!//!assign!var!with!a!String !!!!x!=!var.toInteger()!!!//!no!problem,!no!need!to!cast !!!!var!=!123 !!!!x!=!var.toUpperCase()!//!error,!var!is!int! } 49
  • 98. Gotcha: static checking vs dynamic • Type checking works at compile-time •adding @TypeChecked doesn’t change behavior • do not confuse with static compilation • Most dynamic features cannot be type checked •metaclass changes, categories •dynamically bound variables (ex: script’s binding) • However, compile-time metaprogramming works •as long as proper type information is defined 50
  • 99. Gotcha: runtime metaprogramming @TypeChecked! void.test()!{ !!!!Integer.metaClass.foo!=!{} !!!!123.foo() } 51
  • 100. Gotcha: runtime metaprogramming @TypeChecked! void.test()!{ !!!!Integer.metaClass.foo!=!{} !!!!123.foo() } Not allowed: metaClass property is dynamic 51
  • 101. Gotcha: runtime metaprogramming @TypeChecked! void.test()!{ !!!!Integer.metaClass.foo!=!{} !!!!123.foo() } Method not Not allowed: recognized metaClass property is dynamic 51
  • 102. Gotcha: explicit type for closures @TypeChecked!test()!{ !!!!["a",!"b",!"c"].collect!{ !!!!!!!!it.toUpperCase()!//!Not!OK !!!!} } • A « Groovy Enhancement Proposal » to address the issue 52
  • 103. Gotcha: explicit type for closures @TypeChecked!test()!{ !!!!["a",!"b",!"c"].collect!{!String!it!>> !!!!!!!!it.toUpperCase()!//!OK,!it’s!a!String !!!!} } • A « Groovy Enhancement Proposal » to address the issue 52
  • 104. Closure shared variables @TypeChecked!test()!{ !!!!def!var!=!"abc"!!!!!!! !!!!def!cl!=!{!var!=!new!Date()!} !!!!cl() !!!!var.toUpperCase()!!//!Not!OK! } 53
  • 105. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked!test()!{ !!!!def!var!=!"abc"!!!!!!! !!!!def!cl!=!{!var!=!new!Date()!} !!!!cl() !!!!var.toUpperCase()!!//!Not!OK! } 53
  • 106. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked!test()!{ Impossible to !!!!def!var!=!"abc"!!!!!!! ensure the !!!!def!cl!=!{!var!=!new!Date()!} assignment !!!!cl() really happens !!!!var.toUpperCase()!!//!Not!OK! } 53
  • 107. Closure shared variables var assigned in the closure: «shared closure variable» @TypeChecked!test()!{ Impossible to !!!!def!var!=!"abc"!!!!!!! ensure the !!!!def!cl!=!{!var!=!new!Date()!} assignment !!!!cl() really happens !!!!var.toUpperCase()!!//!Not!OK! } Only methods of the most specific compatible type (LUB) are allowed by the type checker 53
  • 108. Closure shared variables class!A!!!!!!!!!!!{!void.foo()!{}!} class!B!extends!A!{!void.bar()!{}!} @TypeChecked!test()!{ !!!!def!var!=!new!A() !!!!def!cl!=!{!var!=!new!B()!} !!!!cl() !!!!var.foo()!!!//!OK! } 54
  • 109. Closure shared variables class!A!!!!!!!!!!!{!void.foo()!{}!} class!B!extends!A!{!void.bar()!{}!} @TypeChecked!test()!{ !!!!def!var!=!new!A() !!!!def!cl!=!{!var!=!new!B()!} !!!!cl() !!!!var.foo()!!!//!OK! } var is at least an instance of A 54
  • 110. Static Compilation • Given your Groovy code can be type checked... we can as well compile it «statically» • ie. generate the same byte code as javac • Also interesting for those stuck in JDK < 7 to benefit from performance improvements 55
  • 111. Static Compilation: advantages • You gain: • Type safety • thanks to static type checking • static compilation builds upon static type checking • Faster code • as close as possible to Java’s performance • Code immune to «monkey patching» • metaprogramming badly used can interfere with framework code • Smaller bytecode size 56
  • 112. Static Compilation: disadvantages • But you loose: • Dynamic features •metaclass changes, categories, etc. • Dynamic method dispatch •although as close as possible to «dynamic» Groovy 57
  • 113. Statically compiled & dyn methods @CompileStatic String!greeting(String!name)!{ !!!!//!call!method!with!dynamic!behavior !!!!//!but!with!proper!signature !!!!generateMarkup(name.toUpperCase()) } ! //!usual!dynamic!behavior String!generateMarkup(String!name)!{ !!!!def!sw!=!new!StringWriter() !!!!new!MarkupBuilder(sw).html!{ !!!!!!!!body!{ !!!!!!!!!!!!div!name !!!!!!!!} !!!!} !!!!sw.toString() } 58
  • 114. What about performance? • Comparisons between: • Java • Groovy static compilation (Groovy 2.0) • Groovy with primitive optimizations (Groovy 1.8+) • Groovy without optimizations (Groovy 1.7) 59
  • 115. What about performance? Pi (π) Binary Fibonacci quadrature trees Java 188 ms 97 ms 3.6 s Static 1.7 1.8 2.0 compilation 202 ms 101 ms 4.4 s Primitive optimizations 360 ms 111 ms 23.7 s No prim. optimizations 2590 ms 3220 ms 50.0 s 60
  • 116. Summary • Main themes of the Groovy 2.0 release •Modularity • Embark the JDK 7 enhancements •Project Coin •Invoke Dynamic • Static aspects • Static type checking • Static compilation 61
  • 117. 62
  • 118. Thank you! ge e Lafor lopment Gu illaum ovy Deve Gro H ead of om ge@ gmail.c Emai l: glafor forge e :@ gla .to/glaforg Twitter : http://gplus spot.com + pp Google p://glaforge.a tt Blog: h 63
  • 119. Questions & Answers • Got questions, really? Q&A 64
  • 120. Image credits • Bugs bunny: http://storage.canalblog.com/63/56/517188/47634843.jpeg • Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg • Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg • Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg • Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg • Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg • Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg • Road Runner: http://newspaper.li/static/4ada046b7772f0612fec4e3840142308.jpg • Porky: http://joshuadsandy.files.wordpress.com/2011/05/porky-pig-5.jpg • Will E help: http://www.clipart-fr.com/data/clipart/looney/looney_004.jpg • Coyote road runner: http://www.jenkle.com/wp-content/uploads/2010/12/coyote-wallpaper1.jpg • Around the corner: http://3.bp.blogspot.com/-wvfO5NUbi8Q/TzBqTh4SOsI/AAAAAAAADOg/lRE9XVHGiOc/s1600/around-the-corner_large.jpg • Lube: http://images.motorcycle-superstore.com/ProductImages/OG/0000_Motul_Chain_Lube_Road_--.jpg 65