SlideShare a Scribd company logo
1 of 170
Whatʼs new in Groovy 1.8 and beyond?

Guillaume Laforge
Groovy Project Manager
SpringSource, a division of VMware


Twitter: @glaforge
Blog: http://glaforge.appspot.com


© 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Guillaume Laforge

• Groovy Project Manager at VMware
    • Initiator of the Grails framework
    • Creator of the Gaelyk toolkit
• Co-author of Groovy in Action
• Speaking worldwide w/ a French accent


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


2        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Guillaume Laforge

• Groovy Project Manager at VMware
    • Initiator of the Grails framework
    • Creator of the Gaelyk toolkit
• Co-author of Groovy in Action
• Speaking worldwide w/ a French accent


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


2        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




185
3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




185k
3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




185k        FIRST MONTH
            AFTER RELEASE

3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




                                                                     k
3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




177k        SECOND MONTH
            AFTER RELEASE

3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




                                                                     k
3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.7




362k
 USERS?
3   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
?
TIP OF
THE
ICEBERG
Guesstimate




    1/2
                                                                    Users
5
    Million
    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Agenda




6   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Agenda

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




6        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Agenda

• Whatʼs new in Groovy 1.8?
    – Nicer DSLs with command chains expressions
    – Runtime performance improvements
    – GPars bundled for taming your multicores
    – Closure enhancements
    – Builtin JSON support
    – New AST transformations
• Whatʼs cooking for Groovy 1.9?
    – Continued runtime performance improvements
    – Alignments with JDK 7
      • Project Coin (small language changes)

6        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




7   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions


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




7        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions


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




7        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions


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


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




7        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions


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


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




7        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions


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


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


• Let’s have a look at some examples
7        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




          
turn
left

then
right





8   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions
            Alternation of
            method names




          
turn
left

then
right





8   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions
            Alternation of
            method names




          
turn
left

then
right



                                                    and parameters
                                                  (even named ones)




8   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




          
turn
left

then
right





8   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




            Equivalent to:


          




(



).



(




)
          
turn
left

then
right





8   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
LookM  a!
N op are ns,
no do ts!
Command chains expressions



        Before... we used to do...



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




10      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



        Before... we used to do...



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


        Normal argument




10      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



        Before... we used to do...



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


        Normal argument                               Named arguments




10      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



         Before... we used to do...



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


         Normal argument                               Named arguments


      Woud call:
      def
take(Map
m,
Quantity
q)


10       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



         Now, even less punctuation!



     take
2.pills

of

chloroquinine

after

6.hours




11      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



         Now, even less punctuation!



     



(






).


(












).





(






)
     take
2.pills

of

chloroquinine

after

6.hours




11      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions

         //
environment
initialization
         Integer.metaClass.getPills
{
‐>
delegate
}
         Integer.metaClass.getHours
{
‐>
delegate
}
         

         //
variable
injection
         def
chloroquinine
=
/*...*/
         





     {                                                                        }
         //
implementing
the
DSL
logic
         def
take(n)
{
         



[of:
{
drug
‐>
         







[after:
{
time
‐>
/*...*/
}]
         



}]
         }

         //
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
         take
2.pills
of
chloroquinine
after
6.hours

12   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




     take
2.pills

of

chloroquinine

after

6.hours




13      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




     take
2.pills

of

chloroquinine

after

6.hours


                                  ... some dots remain ...




13      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



              Yes, we can... get rid of them :-)



     take
2

pills
of

chloroquinine

after

6
hours




14      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions



              Yes, we can... get rid of them :-)



     



(
).




(

).













(




).
(




)
     take
2

pills
of

chloroquinine

after

6
hours




14      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions

         //
variable
injection
         def
(of,
after,
hours)
=
/*...*/
         

         //
implementing
the
DSL
logic




     {                                                                        }
         def
take(n)
{
         



[pills:
{
of
‐>
         







[chloroquinine:
{
after
‐>
         











['6':
{
time
‐>
}]
         







}]
         



}]
         }

         //
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
         take
2
pills
of
chloroquinine
after
6
hours


15   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Command chains expressions




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names




    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names

 //
possible
with
an
odd
number
of
terms


    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names

 //
possible
with
an
odd
number
of
terms
 take
3

cookies

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor
 



(





).



(










).


(





)

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names

 //
possible
with
an
odd
number
of
terms
 take
3

cookies

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor
 



(





).



(










).


(





)

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good
 




(














).





(



)

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names

 //
possible
with
an
odd
number
of
terms
 take
3

cookies

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor
 



(





).



(










).


(





)

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good
 




(














).





(



)

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}
 




(

).



(

).



(

)

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names

 //
possible
with
an
odd
number
of
terms
 take
3

cookies

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor
 



(





).



(










).


(





)

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good
 




(














).





(



)

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}
 




(

).



(

).



(

)

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names
 





(


).







.



(




)

 //
possible
with
an
odd
number
of
terms
 take
3

cookies

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Command chains expressions

 //
methods
with
multiple
arguments
(commas)
 take
coffee

with
sugar,
milk

and
liquor
 



(





).



(










).


(





)

 //
leverage
named‐args
as
punctuation
 check
that:
margarita

tastes
good
 




(














).





(



)

 //
closure
parameters
for
new
control
structures
 given
{}

when
{}

then
{}
 




(

).



(

).



(

)

 //
zero‐arg
methods
require
parens
 select
all

unique()
from
names
 





(


).







.



(




)

 //
possible
with
an
odd
number
of
terms
 take
3

cookies
 



(
).

    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   16
Runtime performance improvements


• Significant runtime improvements
  for primitive type operations
     – classical Fibonacci example x13 faster!
     – almost as fast as Java


• Some direct method calls on this




17        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
GPars bundled

• GPars is bundled in the Groovy distribution


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


• Don’t miss the following presentations on GPars
     – Paul King — Thursday, 12:45 - 2:15PM
       • Groovy & Concurrency with GPars
     – Venkat Subramaniam — Friday, 8:30 - 10:00AM

18        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure enhancements


• Closure annotation parameters


• Some more functional flavor
     – composition
     – trampoline
     – memoization


• Currying improvements



19        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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)

20    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure annotation parameters
     @Retention(RetentionPolicy.RUNTIME)
     @interface
Invariant
{




     



Class
value()
//
a
closure
class
     }
     


 {   @Invariant({
number
>=
0
})
     class
Distance
{




     



float
number



               an’s G
                                               Cont racts
     



String
unit            P oor-m
     }

     

     def
d
=
new
Distance(number:
10,
unit:
"meters")

     def
anno
=
Distance.getAnnotation(Invariant)
     def
check
=
anno.value().newInstance(d,
d)
     assert
check(d)

20    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure composition

    def
plus2

=
{
it
+
2
}
    def
times3
=
{
it
*
3
}

    

{   def
times3plus2
=
plus2
<<
times3
    assert
times3plus2(3)
==
11
    assert
times3plus2(4)
==
plus2(times3(4))

    

{   def
plus2times3
=
times3
<<
plus2
    assert
plus2times3(3)
==
15
    assert
plus2times3(5)
==
times3(plus2(5))

    

    //
reverse
composition
{   assert
times3plus2(3)
==
(times3
>>
plus2)(3)

     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge   21
Closure trampoline




22   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure trampoline

     def
factorial

     factorial
=
{
int
n,
BigInteger
accu
=
1G
‐>

                                                 

     



if
(n
<
2)
return
accu





     



factorial.trampoline(n
‐
1,
n
*
accu)
     }.trampoline()
     

     assert
factorial(1)



==
1
     assert
factorial(3)



==
1
*
2
*
3
     assert
factorial(1000)
==
402387260...



22       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure memoization




23   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure memoization
     def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize()




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Closure memoization
     def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize()

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




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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






23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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


     





23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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)




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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)
     





23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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




23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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)





23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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


23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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)

23      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Currying improvements




24   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Currying improvements

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


     





24     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Currying improvements

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


     

     //
currying
n‐th
parameter
     def
joinWithSeparator
=

     



{
one,
sep,
two
‐>
one
+
sep
+
two
}
     def
joinWithComma
=

     



joinWithSeparator.ncurry(1,
',
')
     assert
joinWithComma('a',
'b')
==
'a,
b'


24     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Builtin JSON support


• Consuming


• Producing


• Pretty-printing




25     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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
}




26       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Builtin JSON support

         import
groovy.json.*

         

         def
json
=
new
JsonBuilder()

         

         json.person
{




         



name
"Guillaume"
         



age
33




         



pets
"Hector",
"Felix"
         }

         println
json.toString()


27   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Builtin JSON support
     import
groovy.json.*

     

     println
JsonOutput.prettyPrint(
     



'''{"person":{"name":"Guillaume","age":33,'''
+

     



'''"pets":["Hector","Felix"]}}''')
     





28      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Builtin JSON support
     import
groovy.json.*

     

     println
JsonOutput.prettyPrint(
     



'''{"person":{"name":"Guillaume","age":33,'''
+

     



'''"pets":["Hector","Felix"]}}''')
     


                       {




                       



"person":
{








                       







"name":
"Guillaume",



                                                     

                       







"age":
33,








                       







"pets":
[












                       











"Hector",










                                                     

                       











"Felix"








                       







]




                       



}
                       }


28      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New AST transformations

• @Log                                                      – @ConditionalInterrupt


• @Field                                               • @Canonical
                                                            – @ToString,
                                                            – @EqualsAndHashCode,
• @AutoClone
                                                            – @TupleConstructor
• @AutoExternalizable

                                                       • @InheritConstructor
• Controlling the execution of
  your code
     – @ThreadInterrupt,                               • @WithReadLock
     – @TimedInterrupt,                                • @WithWriteLock
29       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@Log

• Four different loggers can be injected
     – @Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy
                  import
groovy.util.logging.*

                  

                  @Log
                  class
Car
{




                  



Car()
{








                  







log.info
'Car
constructed'


                                                     

                  



}
                  }

                  

                  def
c
=
new
Car()


30      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@Log

• Four different loggers can be injected
     – @Log, @Commons, @Log4j, @Slf4j
• Possible to implement your own strategy
                     import
groovy.util.logging.*

                     

                     @Log
                     class
Car
{




Guarded              



Car()
{








w/ an if             







log.info
'Car
constructed'


                                                        

                     



}
                     }

                     

                     def
c
=
new
Car()


30         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@Field

• Surprising scoping rules in scripts
     – variables are local to the run() method
     – variables aren’t visible in methods
       • although visually the variable is in a surrounding scope


• @Field creates a field in the script class
                @Field
List
awe
=
[1,
2,
3]
                def
awesum()
{
awe.sum()
}
                assert
awesum()
==
6



31       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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?




32        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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

32        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@ThreadInterrupt

     @ThreadInterrupt
     import
groovy.transform.ThreadInterrupt

     

     while
(true)
{


     



//
eat
lots
of
CPU
     }




                                                                             33


    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@ThreadInterrupt

      @ThreadInterrupt
      import
groovy.transform.ThreadInterrupt

      

      while
(true)
{

  {   



if
(Thread.currentThread.isInterrupted())
      







throw
new
InterruptedException()                                 }
      



//
eat
lots
of
CPU
      }




                                                                                   33


      @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@ThreadInterrupt

       @ThreadInterrupt
       import
groovy.transform.ThreadInterrupt

       

       while
(true)
{

   {   



if
(Thread.currentThread.isInterrupted())
       







throw
new
InterruptedException()                                 }
       



//
eat
lots
of
CPU
       }



• Two optional annotation parameters available
  – checkOnMethodStart (true by default)
  – applyToAllClasses (true by default)

                                                                                    33


       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@TimedInterrupt

           @TimedInterrupt(10)
           import
groovy.transform.TimedInterrupt

           

           while
(true)
{
           



//
eat
lots
of
CPU
           }


• InterruptedException thrown when checks indicate code
  ran longer than desired


• Optional annotation parameters available
     – same as @ThreadInterrupt
     – value: for an amount of time duration
34   – unit: for the time duration unit (TimeUnit.SECONDS)
         @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
@ConditionalInterrupt

• Specify your own condition to be inserted
  at the start of method and closure bodies
     – check for available resources, number of times run, etc.
• Leverages closure annotation parameters from Groovy 1.8
           @ConditionalInterrupt({
counter++
>
2
})
           import
groovy.transform.ConditionalInterrupt
           import
groovy.transform.Field

           

           @Field
int
counter
=
0


           100.times
{




           



println
'executing
script
method...'
           }


35       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@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)


36       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@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()




37    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@TupleConstructor

• Provides a «classical» constructor with all properties
• Several annotation parameter options available
          import
groovy.transform.TupleConstructor

          

          @TupleConstructor

          class
Person
{




          



String
name




          



int
age
          }

          

          def
m
=
new
Person('Marion',
3)






          

          assert
m.name
==
'Marion'
          assert
m.age

==
3


38    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@Canonical


• One annotation to rule them all!
     – @Canonical mixes together
       • @ToString
       • @EqualsAndHashCode
       • @TupleConstructor


• You can customize behavior by combining
  @Canonical and one of the other annotations




39       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@InheritConstructor

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




 class
CustomException
extends
Exception
{
 



CustomException()























{
super()






}
 



CustomException(String
msg)













{
super(msg)



}
 



CustomException(String
msg,
Throwable
t)
{
super(msg,
t)
}
 



CustomException(Throwable
t)












{
super(t)





}
 }




40     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@InheritConstructor

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

 import
groovy.transform.*

 @InheritConstructors
 class
CustomException
extends
Exception
{
 



CustomException()























{
super()






}
 



CustomException(String
msg)













{
super(msg)



}
 



CustomException(String
msg,
Throwable
t)
{
super(msg,
t)
}
 



CustomException(Throwable
t)












{
super(t)





}
 }




40     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@WithReadLock, @WithWriteLock

     import
groovy.transform.*

     

     class
ResourceProvider
{




     



private
final
Map<String,
String>
data
=
new
HashMap<>()
     

     



@WithReadLock




     



String
getResource(String
key)
{








     







return
data.get(key)




     



}





     

     



@WithWriteLock




     



void
refresh()
{








     







//reload
the
resources
into
memory




     



}
     }


41       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
@WithReadLock, @WithWriteLock

     import
groovy.transform.*

     

     class
ResourceProvider
{




     



private
final
Map<String,
String>
data
=
new
HashMap<>()
     

{    



@WithReadLock




     



String
getResource(String
key)
{








     







return
data.get(key)




     



}





     

{    



@WithWriteLock




     



void
refresh()
{








     







//reload
the
resources
into
memory




     



}
     }


41       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Miscelanous



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




42     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Compilation customizers


• Ability to apply some customization to the Groovy
  compilation process


• Three available customizers
     – ImportCustomizer
     – SecureASTCustomizer
     – ASTTransformationCustomizer


• But you can implement your own

43       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Imports customizer


     def
configuration
=
new
CompilerConfiguration()
     

     def
custo
=
new
ImportCustomizer()
     custo.addStaticStar(Math.name)
     configuration.addCompilationCustomizers(custo)

     

     def
result
=
new
GroovyShell(configuration)
     



.evaluate("
cos
PI/3
")




44       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Applying an AST transformation

     def
configuration
=
new
CompilerConfiguration()

     configuration.addCompilationCustomizers(
     



new
ASTTransformationCustomizer(Log))

     

     new
GroovyShell(configuration).evaluate("""
     



class
Car
{








     







Car()
{












     











log.info
'Car
constructed'








     







}




     



}





     



log.info
'Constructing
a
car'




     



def
c
=
new
Car()
     """)



45   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Secure AST customizer

                     Idea: Implement an «arithmetic shell»
                       Being able control what a user script is
                       allowed to do: only arithmetic expressions


• Let’s setup our environment
      – some imports
      – an import customizer to import java.lang.Math.*
      – prepare a secure AST customizer
     import
org.codehaus.groovy.control.customizers.*
     import
org.codehaus.groovy.control.*
     import
static
org.codehaus.groovy.syntax.Types.*
     

     def
imports
=
new
ImportCustomizer().addStaticStars('java.lang.Math')
     def
secure
=
new
SecureASTCustomizer()


46         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Secure AST customizer

     ...
     secure.with
{
       //
disallow
closure
creation
       closuresAllowed
=
false

       //
disallow
method
definitions
       methodDefinitionAllowed
=
false

     

       //
empty
white
list
=>
forbid
imports
       importsWhitelist
=
[]

       staticImportsWhitelist
=
[]
       //
only
allow
the
java.lang.Math.*
static
import
       staticStarImportsWhitelist
=
['java.lang.Math'
     ...



47       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Secure AST customizer
     ...
        //
language
tokens
allowed
        tokensWhitelist
=
[
           PLUS,
MINUS,
MULTIPLY,
DIVIDE,
MOD,
POWER,
PLUS_PLUS,

           MINUS_MINUS,
COMPARE_EQUAL,
COMPARE_NOT_EQUAL,

           COMPARE_LESS_THAN,
COMPARE_LESS_THAN_EQUAL,

           COMPARE_GREATER_THAN,
COMPARE_GREATER_THAN_EQUAL
        ]
     

        //
types
allowed
to
be
used
(including
primitive
types)
        constantTypesClassesWhiteList
=
[
           Integer,
Float,
Long,
Double,
BigDecimal,

           Integer.TYPE,
Long.TYPE,
Float.TYPE,
Double.TYPE
        ]
     

        //
classes
who
are
allowed
to
be
receivers
of
method
calls
        receiversClassesWhiteList
=
[

           Math,
Integer,
Float,
Double,
Long,
BigDecimal
]
     }
     ...

48         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Secure AST customizer

• Ready to evaluate our arithmetic expressions!
     ...
     def
config
=
new
CompilerConfiguration()
     config.addCompilationCustomizers(imports,
secure)

     def
shell
=
new
GroovyShell(config)
     

     shell.evaluate
'cos
PI/3'




• But the following would have failed:
              shell.evaluate
'System.exit(0)'


49     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Slashy and dollar slashy strings

• Slashy strings are now multiline
     – particularly handy for multi-line regexs


• Dollar slashy string notation introduced
             def
(name,
date)
=
["Guillaume",
"Oct,
26th"]
             def
dollarSlashy
=
$/




             



Hello
$name,
today
we're
${date}
             



$
dollar‐sign




             



$$
dollar‐sign




             




backslash




             



/
slash




             


$/
slash
             /$



50       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods




51   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     





51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     





51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]





51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1
     





51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1
     

     //
map
withDefault()




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1
     

     //
map
withDefault()
     def
words
=
"one
two
two
three
three
three".split()




51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1
     

     //
map
withDefault()
     def
words
=
"one
two
two
three
three
three".split()
     def
freq
=
[:].withDefault
{
k
‐>
0
}



51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
New GDK methods
     //
count
     assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5
     

     //
count
by
     assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
}
     assert
[(true):2,
(false):4]

     



==
'Groovy'.toList().countBy{
it
==
'o'
}
     

     //
min/max
for
maps
with
closures
     def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]

     assert
map.max
{
it.key.size()
}.key
==
'dddd'
     assert
map.min
{
it.value
}.value
==
1
     

     //
map
withDefault()
     def
words
=
"one
two
two
three
three
three".split()
     def
freq
=
[:].withDefault
{
k
‐>
0
}
     words.each
{
freq[it]
+=
1
}

51    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion




52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{








52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue




52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as




52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              

              //
implicit
coercion




52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              

              //
implicit
coercion
              Color
b
=
"blue"





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              

              //
implicit
coercion
              Color
b
=
"blue"

              





52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              

              //
implicit
coercion
              Color
b
=
"blue"

              

              //
with
GStrings
too



52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
(G)String to Enum coercion

              enum
Color
{




              



red,
green,
blue
              }

              

              //
coercion
with
as
              def
r
=
"red"
as
Color

              

              //
implicit
coercion
              Color
b
=
"blue"

              

              //
with
GStrings
too
              def
g
=
"${'green'}"
as
Color


52   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Customizing the Groovysh prompt




53   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Launching remote scripts

• With the Groovy command, you can launch remote scripts
     >
groovy
http://groovyconsole.appspot.com/raw/110001




• Be careful to what
  you’re executing :-)




54        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
What’s
cooking
for 1.9?
Groovy 1.9 roadmap

• Java 7 alignements: Project Coin
     – binary literals
     – underscore in literals
     – multicatch
• JDK 7: InvokeDynamic
• Towards a more modular Groovy
• Static type checking and compilation
• Miscelanous


• What else? Your call!

56        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy 1.9 roadmap

• Java 7 alignements: Project Coin
     – binary literals
     – underscore in literals
     – multicatch
• JDK 7: InvokeDynamic
• Towards a more modular Groovy
• Static type checking and compilation
• Miscelanous


• What else? Your call!

56        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Java 7 / JDK 7

• Project Coin and InvokeDynamic




57    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Binary literals

• We had decimal, octal and hexadecimal notations
  for number literals



                  int
x
=
0b10101111
                  assert
x
==
175
                  

                  byte
aByte
=
0b00100001
                  assert
aByte
==
33
                  

                  int
anInt
=
0b1010000101000101
                  assert
anInt
==
41285


58    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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




59     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Multicatch


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


      try
{
      



/*
...
*/
      }
catch(IOException
|
NullPointerException
e)
{
      



/*
one
block
to
treat
2
exceptions
*/
      }




60       @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
InvokeDynamic


• Groovy 1.9 will support JDK 7ʼs invokeDynamic
     – an «indy» branch started recently
     – compiler will have a flag for compiling against JDK 7


• Benefits
     – more runtime performance!
     – in the long run, will allow us to get rid of code!
       • call site caching, thanks to MethodHandles
       • metaclass registry, thanks to ClassValues
       • will let the JIT inline calls more easily

61        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Groovy Modularity

• Groovy’s «all» JAR weighs in at 4MB


• Nobody needs everything
     – Template engine, Ant scripting, Swing UI building...


• Provide a smaller core
     – and several smaller JARs per feature


• Paul King covers Groovy modularisation
     – Wednesday, 12:45-2:15PM


62        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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
63        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
A typo in your variable or method names

 import
groovy.transform.StaticTypes
 

 void
method()
{}
 

 @TypeChecked
test()
{
 



//
Cannot
find
matching
method
metthhoood()
 



metthhoood()
 

 



def
name
=
"Guillaume"
 



//
variable
naamme
is
undeclared
 



println
naamme
 }




64    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
A typo in your variable or method names

 import
groovy.transform.StaticTypes
 

 void
method()
{}
 

 @TypeChecked
test()
{
 



//
Cannot
find
matching
method
metthhoood()
 



metthhoood()
 

 



def
name
=
"Guillaume"
 



//
variable
naamme
is
undeclared                                          Compilation
 



println
naamme                                                              errors!
 }




64    @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Complain on wrong assignments

 //
cannot
assign
value
of
type...
to
variable...
 int
x
=
new
Object()
 Set
set
=
new
Object()
 

 def
o
=
new
Object()
 int
x
=
o
 

 String[]
strings
=
['a','b','c']
 int
str
=
strings[0]
 

 //
cannot
find
matching
method
plus()
 int
i
=
0
 i
+=
'1'




65     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Complain on wrong assignments

 //
cannot
assign
value
of
type...
to
variable...
 int
x
=
new
Object()
 Set
set
=
new
Object()                                                         Compilation
 
                                                                              errors!
 def
o
=
new
Object()
 int
x
=
o
 

 String[]
strings
=
['a','b','c']
 int
str
=
strings[0]
 

 //
cannot
find
matching
method
plus()
 int
i
=
0
 i
+=
'1'




65     @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Complain on wrong return types

     String
method()
{
'String'
}
     //
cannot
assign
value
of
type
String...
     int
x
=
method()

     //
checks
if/else
branch
return
values
     int
method()
{
     



if
(true)
{
'String'
}
     



else
{
42
}
     }
     //
works
for
switch/case
&
try/catch/finally
     

     //
transparent
toString()
implied
     String
greeting(String
name)
{
     



def
sb
=
new
StringBuilder()
     



sb
<<
"Hi"
<<
name
     }

66        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Complain on wrong return types

     String
method()
{
'String'
}
     //
cannot
assign
value
of
type
String...
     int
x
=
method()                                                              Compilation
                                                                                   errors!
     //
checks
if/else
branch
return
values
     int
method()
{
     



if
(true)
{
'String'
}
     



else
{
42
}
     }
     //
works
for
switch/case
&
try/catch/finally
     

     //
transparent
toString()
implied
     String
greeting(String
name)
{
     



def
sb
=
new
StringBuilder()
     



sb
<<
"Hi"
<<
name
     }

66        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
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
     



}
     }


67   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Staticly checked method & dynamic method
          @TypeChecked
          String
greeting(String
name)
{
          



//
call
method
with
dynamic
behavior
          



//
but
with
proper
signature
          



generateMarkup(name.toUpperCase())
          }
          

          //
usual
dynamic
behavior
          String
generateMarkup(String
name)
{
          



def
sw
=
new
StringWriter()
          



new
MarkupBuilder(sw).html
{
          







body
{
          











div
name
          







}
          



}
          



sw.toString()
          }

68   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Bytecode viewer

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




69        @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Disable Global AST transformations
     //
witout
a
specific
configuration,
the
AST
builder
works
     def
shell
=
new
GroovyShell()
     shell.evaluate(script)
//
passes

     def
config
=
new
CompilerConfiguration()
     config.disabledGlobalASTTransformations
=
     



['org.codehaus.groovy.ast.builder.AstBuilderTransformation']
     def
script
=
'''
     



import
org.codehaus.groovy.ast.builder.AstBuilder
     



new
AstBuilder().buildFromCode
{
"Hello"
}
     '''
     

     //
now
with
the
configuration
in
place,
     //
the
AST
builder
transform
is
not
applied
     shell
=
new
GroovyShell(config)
//
<‐‐
with
the
configuration
     shouldFail
{
     



shell.evaluate(script)
//
fails
     }


70         @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Summary




71   @glaforge — http://glaforge.appspot.com   —
                                                              ROCKS!
                                                   http://gplus.to/glaforge
Thank you!




                                        e
                                L aforg pment
                       aume vy Develo
                 Guill Groo                   m
                 Hea d of           g mail.co
                            aforge@
                    mail: gl glaforge                  e
                  E          @              o /glaforg
                  T witter : http://gplus.t
                   Go ogle+:




72   @glaforge — http://glaforge.appspot.com   —   http://gplus.to/glaforge
Q&A — Got questions, Really?




73   © 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
Image credits
•    Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg

•    Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2

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

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

•    Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/

•    Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg

•    Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg

•    Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg

•    Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg

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

•    Caution: http://www.jeunes-epinay-sur-seine.fr/wp-content/uploads/2010/11/caution-colocation.jpg

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

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

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

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

•    WIP: http://www.connetport.com/wp-content/uploads/Work_in_progress.svg_.png

•    Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg

•




74                @glaforge — http://glaforge.appspot.com                        —       http://gplus.to/glaforge

More Related Content

What's hot

SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)Robert Swisher
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAnderson Aguiar
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeDamien Seguin
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.jsBo-Yi Wu
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidenceJohn Congdon
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloManageIQ
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overviewmarpierc
 
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
 
Converting Your Dev Environment to a Docker Stack - php[world]
Converting Your Dev Environment to a Docker Stack - php[world]Converting Your Dev Environment to a Docker Stack - php[world]
Converting Your Dev Environment to a Docker Stack - php[world]Dana Luther
 
Write book in markdown
Write book in markdownWrite book in markdown
Write book in markdownLarry Cai
 
Converting Your Dev Environment to a Docker Stack - Cascadia
Converting Your Dev Environment to a Docker Stack - CascadiaConverting Your Dev Environment to a Docker Stack - Cascadia
Converting Your Dev Environment to a Docker Stack - CascadiaDana Luther
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionJoshua Thijssen
 
Pugs: A Perl 6 Implementation
Pugs: A Perl 6 ImplementationPugs: A Perl 6 Implementation
Pugs: A Perl 6 ImplementationAudrey Tang
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated FeaturesMark Niebergall
 
Scalable Systems Management with Puppet
Scalable Systems Management with PuppetScalable Systems Management with Puppet
Scalable Systems Management with PuppetPuppet
 
PHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding stylePHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding styleBo-Yi Wu
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with PuppetAlessandro Franceschi
 
Flavors of Concurrency in Java
Flavors of Concurrency in JavaFlavors of Concurrency in Java
Flavors of Concurrency in JavaJavaDayUA
 

What's hot (20)

SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)
 
Automating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with GulpAutomating Large Applications on Modular and Structured Form with Gulp
Automating Large Applications on Modular and Structured Form with Gulp
 
Frontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the likeFrontend JS workflow - Gulp 4 and the like
Frontend JS workflow - Gulp 4 and the like
 
Automating your workflow with Gulp.js
Automating your workflow with Gulp.jsAutomating your workflow with Gulp.js
Automating your workflow with Gulp.js
 
Release with confidence
Release with confidenceRelease with confidence
Release with confidence
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
 
GTLAB Overview
GTLAB OverviewGTLAB Overview
GTLAB Overview
 
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
 
Converting Your Dev Environment to a Docker Stack - php[world]
Converting Your Dev Environment to a Docker Stack - php[world]Converting Your Dev Environment to a Docker Stack - php[world]
Converting Your Dev Environment to a Docker Stack - php[world]
 
Write book in markdown
Write book in markdownWrite book in markdown
Write book in markdown
 
Converting Your Dev Environment to a Docker Stack - Cascadia
Converting Your Dev Environment to a Docker Stack - CascadiaConverting Your Dev Environment to a Docker Stack - Cascadia
Converting Your Dev Environment to a Docker Stack - Cascadia
 
Troubleshooting Puppet
Troubleshooting PuppetTroubleshooting Puppet
Troubleshooting Puppet
 
Puppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 EditionPuppet for dummies - ZendCon 2011 Edition
Puppet for dummies - ZendCon 2011 Edition
 
Pugs: A Perl 6 Implementation
Pugs: A Perl 6 ImplementationPugs: A Perl 6 Implementation
Pugs: A Perl 6 Implementation
 
1. MySql plugins
1. MySql plugins1. MySql plugins
1. MySql plugins
 
PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated Features
 
Scalable Systems Management with Puppet
Scalable Systems Management with PuppetScalable Systems Management with Puppet
Scalable Systems Management with Puppet
 
PHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding stylePHP & JavaScript & CSS Coding style
PHP & JavaScript & CSS Coding style
 
Developing IT infrastructures with Puppet
Developing IT infrastructures with PuppetDeveloping IT infrastructures with Puppet
Developing IT infrastructures with Puppet
 
Flavors of Concurrency in Java
Flavors of Concurrency in JavaFlavors of Concurrency in Java
Flavors of Concurrency in Java
 

Similar to Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - SpringOne2GX 2011

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
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programsBadoo Development
 
Hand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebHand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebSugree Phatanapherom
 
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
 
Advanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentAdvanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentMike Brittain
 
Android Course - Lesson6
 Android Course - Lesson6 Android Course - Lesson6
Android Course - Lesson6Callum Taylor
 
Flow Product Development
Flow Product DevelopmentFlow Product Development
Flow Product DevelopmentPablo Domingo
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeMário Almeida
 
Continuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPContinuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPKAI CHU CHUNG
 
Automating with operators - FossAsia Summit 2019
Automating with operators - FossAsia Summit 2019Automating with operators - FossAsia Summit 2019
Automating with operators - FossAsia Summit 2019Jorge Morales
 
GitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementGitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementJohn Anderson
 
Feedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeFeedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeHaja R
 
Fundamentals of programming finals.ajang
Fundamentals of programming finals.ajangFundamentals of programming finals.ajang
Fundamentals of programming finals.ajangJaricka Angelyd Marquez
 
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment PatternsHow do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment PatternsThoughtworks
 
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns ThoughtWorks Studios
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy RESTRestlet
 
MySQL Group Replication - HandsOn Tutorial
MySQL Group Replication - HandsOn TutorialMySQL Group Replication - HandsOn Tutorial
MySQL Group Replication - HandsOn TutorialKenny Gryp
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開KAI CHU CHUNG
 

Similar to Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - SpringOne2GX 2011 (20)

Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
 
Profiling and optimizing go programs
Profiling and optimizing go programsProfiling and optimizing go programs
Profiling and optimizing go programs
 
Hand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWebHand-on Resources II: Extending SCMSWeb
Hand-on Resources II: Extending SCMSWeb
 
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...
 
Advanced Topics in Continuous Deployment
Advanced Topics in Continuous DeploymentAdvanced Topics in Continuous Deployment
Advanced Topics in Continuous Deployment
 
Android Course - Lesson6
 Android Course - Lesson6 Android Course - Lesson6
Android Course - Lesson6
 
Flow Product Development
Flow Product DevelopmentFlow Product Development
Flow Product Development
 
Angboard
AngboardAngboard
Angboard
 
Android reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skypeAndroid reverse engineering - Analyzing skype
Android reverse engineering - Analyzing skype
 
Continuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCPContinuous Integration & Continuous Delivery with GCP
Continuous Integration & Continuous Delivery with GCP
 
Automating with operators - FossAsia Summit 2019
Automating with operators - FossAsia Summit 2019Automating with operators - FossAsia Summit 2019
Automating with operators - FossAsia Summit 2019
 
GitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo ManagementGitGot: The Swiss Army Chainsaw of Git Repo Management
GitGot: The Swiss Army Chainsaw of Git Repo Management
 
Feedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCodeFeedback en continu grâce au TDD et au AsCode
Feedback en continu grâce au TDD et au AsCode
 
Fundamentals of programming finals.ajang
Fundamentals of programming finals.ajangFundamentals of programming finals.ajang
Fundamentals of programming finals.ajang
 
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment PatternsHow do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
 
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
How do you implement Continuous Delivery?: Part 5 - Deployment Patterns
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy REST
 
MySQL Group Replication - HandsOn Tutorial
MySQL Group Replication - HandsOn TutorialMySQL Group Replication - HandsOn Tutorial
MySQL Group Replication - HandsOn Tutorial
 
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
60分鐘完送百萬edm,背後雲端ci/cd實戰大公開
 

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 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Guillaume 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
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGuillaume 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
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Guillaume 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
 
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 (20)

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012
 
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
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume 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 Languages
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
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
 
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

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 

Recently uploaded (20)

Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 

Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - SpringOne2GX 2011

  • 1. Whatʼs new in Groovy 1.8 and beyond? Guillaume Laforge Groovy Project Manager SpringSource, a division of VMware Twitter: @glaforge Blog: http://glaforge.appspot.com © 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
  • 2. Guillaume Laforge • Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaking worldwide w/ a French accent • Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge 2 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 3. Guillaume Laforge • Groovy Project Manager at VMware • Initiator of the Grails framework • Creator of the Gaelyk toolkit • Co-author of Groovy in Action • Speaking worldwide w/ a French accent • Follow me on... • My blog: http://glaforge.appspot.com • Twitter: @glaforge • Google+: http://gplus.to/glaforge 2 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 4. Groovy 1.7 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 5. Groovy 1.7 185 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 6. Groovy 1.7 185k 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 7. Groovy 1.7 185k FIRST MONTH AFTER RELEASE 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 8. Groovy 1.7 k 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 9. Groovy 1.7 177k SECOND MONTH AFTER RELEASE 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 10. Groovy 1.7 k 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 11. Groovy 1.7 362k USERS? 3 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 13. Guesstimate 1/2 Users 5 Million @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 14. Agenda 6 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 15. Agenda • Whatʼs new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations 6 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 16. Agenda • Whatʼs new in Groovy 1.8? – Nicer DSLs with command chains expressions – Runtime performance improvements – GPars bundled for taming your multicores – Closure enhancements – Builtin JSON support – New AST transformations • Whatʼs cooking for Groovy 1.9? – Continued runtime performance improvements – Alignments with JDK 7 • Project Coin (small language changes) 6 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 17. Command chains expressions 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 18. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 19. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 20. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 21. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 22. Command chains expressions • A grammar improvement allowing you to drop dots & parens when chaining method calls – an extended version of top-level statements like println • Less dots, less parens allow you to – write more readable business rules – in almost plain English sentences • (or any language, of course) • Let’s have a look at some examples 7 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 23. Command chains expressions 
turn
left

then
right
 8 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 24. Command chains expressions Alternation of method names 
turn
left

then
right
 8 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 25. Command chains expressions Alternation of method names 
turn
left

then
right
 and parameters (even named ones) 8 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 26. Command chains expressions 
turn
left

then
right
 8 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 27. Command chains expressions Equivalent to: 




(



).



(




) 
turn
left

then
right
 8 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 28. LookM a! N op are ns, no do ts!
  • 29. Command chains expressions Before... we used to do... take
2.pills,
of:
chloroquinine,
after:
6.hours 10 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 30. Command chains expressions Before... we used to do... take
2.pills,
of:
chloroquinine,
after:
6.hours Normal argument 10 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 31. Command chains expressions Before... we used to do... take
2.pills,
of:
chloroquinine,
after:
6.hours Normal argument Named arguments 10 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 32. Command chains expressions Before... we used to do... take
2.pills,
of:
chloroquinine,
after:
6.hours Normal argument Named arguments Woud call: def
take(Map
m,
Quantity
q) 10 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 33. Command chains expressions Now, even less punctuation! take
2.pills

of

chloroquinine

after

6.hours 11 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 34. Command chains expressions Now, even less punctuation! 



(






).


(












).





(






) take
2.pills

of

chloroquinine

after

6.hours 11 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 35. Command chains expressions //
environment
initialization Integer.metaClass.getPills
{
‐>
delegate
} Integer.metaClass.getHours
{
‐>
delegate
} 
 //
variable
injection def
chloroquinine
=
/*...*/ 
 { } //
implementing
the
DSL
logic def
take(n)
{ 



[of:
{
drug
‐> 







[after:
{
time
‐>
/*...*/
}] 



}] } //
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take
2.pills
of
chloroquinine
after
6.hours 12 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 36. Command chains expressions take
2.pills

of

chloroquinine

after

6.hours 13 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 37. Command chains expressions take
2.pills

of

chloroquinine

after

6.hours ... some dots remain ... 13 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 38. Command chains expressions Yes, we can... get rid of them :-) take
2

pills
of

chloroquinine

after

6
hours 14 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 39. Command chains expressions Yes, we can... get rid of them :-) 



(
).




(

).













(




).
(




) take
2

pills
of

chloroquinine

after

6
hours 14 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 40. Command chains expressions //
variable
injection def
(of,
after,
hours)
=
/*...*/ 
 //
implementing
the
DSL
logic { } def
take(n)
{ 



[pills:
{
of
‐> 







[chloroquinine:
{
after
‐> 











['6':
{
time
‐>
}] 







}] 



}] } //
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ take
2
pills
of
chloroquinine
after
6
hours 15 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 41. Command chains expressions @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 42. Command chains expressions //
methods
with
multiple
arguments
(commas) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 43. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 44. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 45. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 46. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 47. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 48. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 49. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens select
all

unique()
from
names @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 50. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens select
all

unique()
from
names //
possible
with
an
odd
number
of
terms @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 51. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens select
all

unique()
from
names //
possible
with
an
odd
number
of
terms take
3

cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 52. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor 



(





).



(










).


(





) //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens select
all

unique()
from
names //
possible
with
an
odd
number
of
terms take
3

cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 53. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor 



(





).



(










).


(





) //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good 




(














).





(



) //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} //
zero‐arg
methods
require
parens select
all

unique()
from
names //
possible
with
an
odd
number
of
terms take
3

cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 54. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor 



(





).



(










).


(





) //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good 




(














).





(



) //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} 




(

).



(

).



(

) //
zero‐arg
methods
require
parens select
all

unique()
from
names //
possible
with
an
odd
number
of
terms take
3

cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 55. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor 



(





).



(










).


(





) //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good 




(














).





(



) //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} 




(

).



(

).



(

) //
zero‐arg
methods
require
parens select
all

unique()
from
names 





(


).







.



(




) //
possible
with
an
odd
number
of
terms take
3

cookies @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 56. Command chains expressions //
methods
with
multiple
arguments
(commas) take
coffee

with
sugar,
milk

and
liquor 



(





).



(










).


(





) //
leverage
named‐args
as
punctuation check
that:
margarita

tastes
good 




(














).





(



) //
closure
parameters
for
new
control
structures given
{}

when
{}

then
{} 




(

).



(

).



(

) //
zero‐arg
methods
require
parens select
all

unique()
from
names 





(


).







.



(




) //
possible
with
an
odd
number
of
terms take
3

cookies 



(
). @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 16
  • 57. Runtime performance improvements • Significant runtime improvements for primitive type operations – classical Fibonacci example x13 faster! – almost as fast as Java • Some direct method calls on this 17 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 58. GPars bundled • GPars is bundled in the Groovy distribution • GPars covers a wide range of parallel and concurrent paradigms – actors, fork/join, map/filter/reduce, dataflow, agents, STM – parallel arrays, executors, and more... • Don’t miss the following presentations on GPars – Paul King — Thursday, 12:45 - 2:15PM • Groovy & Concurrency with GPars – Venkat Subramaniam — Friday, 8:30 - 10:00AM 18 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 59. Closure enhancements • Closure annotation parameters • Some more functional flavor – composition – trampoline – memoization • Currying improvements 19 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 60. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface
Invariant
{



 



Class
value()
//
a
closure
class } 
 { @Invariant({
number
>=
0
}) class
Distance
{



 



float
number



 



String
unit }
 
 def
d
=
new
Distance(number:
10,
unit:
"meters")
 def
anno
=
Distance.getAnnotation(Invariant) def
check
=
anno.value().newInstance(d,
d) assert
check(d) 20 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 61. Closure annotation parameters @Retention(RetentionPolicy.RUNTIME) @interface
Invariant
{



 



Class
value()
//
a
closure
class } 
 { @Invariant({
number
>=
0
}) class
Distance
{



 



float
number



 an’s G Cont racts 



String
unit P oor-m }
 
 def
d
=
new
Distance(number:
10,
unit:
"meters")
 def
anno
=
Distance.getAnnotation(Invariant) def
check
=
anno.value().newInstance(d,
d) assert
check(d) 20 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 62. Closure composition def
plus2

=
{
it
+
2
} def
times3
=
{
it
*
3
}
 
 { def
times3plus2
=
plus2
<<
times3 assert
times3plus2(3)
==
11 assert
times3plus2(4)
==
plus2(times3(4))
 
 { def
plus2times3
=
times3
<<
plus2 assert
plus2times3(3)
==
15 assert
plus2times3(5)
==
times3(plus2(5))
 
 //
reverse
composition { assert
times3plus2(3)
==
(times3
>>
plus2)(3) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge 21
  • 63. Closure trampoline 22 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 64. Closure trampoline def
factorial factorial
=
{
int
n,
BigInteger
accu
=
1G
‐>
 
 



if
(n
<
2)
return
accu




 



factorial.trampoline(n
‐
1,
n
*
accu) }.trampoline() 
 assert
factorial(1)



==
1 assert
factorial(3)



==
1
*
2
*
3 assert
factorial(1000)
==
402387260... 22 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 65. Closure memoization 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 66. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 67. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 68. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 69. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 70. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 71. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 72. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 73. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 74. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 
 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 75. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 
 //
at
most
10
invocations
cached 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 76. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 
 //
at
most
10
invocations
cached def
plusAtMost
=
{
...
}.memoizeAtMost(10)
 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 77. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 
 //
at
most
10
invocations
cached def
plusAtMost
=
{
...
}.memoizeAtMost(10)
 //
between
10
and
20
invocations
cached 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 78. Closure memoization def
plus
=
{
a,
b
‐>
sleep
1000;
a
+
b
}.memoize() assert
plus(1,
2)
==
3
//
after
1000ms assert
plus(1,
2)
==
3
//
return
immediately assert
plus(2,
2)
==
4
//
after
1000ms assert
plus(2,
2)
==
4
//
return
immediately

 
 //
at
least
10
invocations
cached def
plusAtLeast
=
{
...
}.memoizeAtLeast(10) 
 //
at
most
10
invocations
cached def
plusAtMost
=
{
...
}.memoizeAtMost(10)
 //
between
10
and
20
invocations
cached def
plusAtLeast
=
{
...
}.memoizeBetween(10,
20) 23 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 79. Currying improvements 24 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 80. Currying improvements //
right
currying def
divide
=
{
a,
b
‐>
a
/
b
} def
halver
=
divide.rcurry(2) assert
halver(8)
==
4

 
 24 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 81. Currying improvements //
right
currying def
divide
=
{
a,
b
‐>
a
/
b
} def
halver
=
divide.rcurry(2) assert
halver(8)
==
4

 
 //
currying
n‐th
parameter def
joinWithSeparator
=
 



{
one,
sep,
two
‐>
one
+
sep
+
two
} def
joinWithComma
=
 



joinWithSeparator.ncurry(1,
',
') assert
joinWithComma('a',
'b')
==
'a,
b' 24 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 82. Builtin JSON support • Consuming • Producing • Pretty-printing 25 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 83. 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
} 26 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 84. Builtin JSON support import
groovy.json.*
 
 def
json
=
new
JsonBuilder()
 
 json.person
{



 



name
"Guillaume" 



age
33



 



pets
"Hector",
"Felix" }
 println
json.toString() 27 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 85. Builtin JSON support import
groovy.json.*
 
 println
JsonOutput.prettyPrint( 



'''{"person":{"name":"Guillaume","age":33,'''
+
 



'''"pets":["Hector","Felix"]}}''') 
 28 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 86. Builtin JSON support import
groovy.json.*
 
 println
JsonOutput.prettyPrint( 



'''{"person":{"name":"Guillaume","age":33,'''
+
 



'''"pets":["Hector","Felix"]}}''') 
 {



 



"person":
{







 







"name":
"Guillaume",


 
 







"age":
33,







 







"pets":
[











 











"Hector",









 
 











"Felix"







 







]



 



} } 28 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 87. New AST transformations • @Log – @ConditionalInterrupt • @Field • @Canonical – @ToString, – @EqualsAndHashCode, • @AutoClone – @TupleConstructor • @AutoExternalizable • @InheritConstructor • Controlling the execution of your code – @ThreadInterrupt, • @WithReadLock – @TimedInterrupt, • @WithWriteLock 29 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 88. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import
groovy.util.logging.*
 
 @Log class
Car
{



 



Car()
{







 







log.info
'Car
constructed'

 
 



} }
 
 def
c
=
new
Car() 30 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 89. @Log • Four different loggers can be injected – @Log, @Commons, @Log4j, @Slf4j • Possible to implement your own strategy import
groovy.util.logging.*
 
 @Log class
Car
{



 Guarded 



Car()
{







 w/ an if 







log.info
'Car
constructed'

 
 



} }
 
 def
c
=
new
Car() 30 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 90. @Field • Surprising scoping rules in scripts – variables are local to the run() method – variables aren’t visible in methods • although visually the variable is in a surrounding scope • @Field creates a field in the script class @Field
List
awe
=
[1,
2,
3] def
awesum()
{
awe.sum()
} assert
awesum()
==
6 31 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 91. Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? 32 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 92. Controlling code execution • Your application may run user’s code – what if the code runs in infinite loops or for too long? – what if the code consumes too many resources? • 3 new transforms at your rescue – @ThreadInterrupt: adds Thread#isInterrupted checks so your executing thread stops when interrupted – @TimedInterrupt: adds checks in method and closure bodies to verify it’s run longer than expected – @ConditionalInterrupt: adds checks with your own conditional logic to break out from the user code 32 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 93. @ThreadInterrupt @ThreadInterrupt import
groovy.transform.ThreadInterrupt
 
 while
(true)
{ 



//
eat
lots
of
CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 94. @ThreadInterrupt @ThreadInterrupt import
groovy.transform.ThreadInterrupt
 
 while
(true)
{ { 



if
(Thread.currentThread.isInterrupted()) 







throw
new
InterruptedException() } 



//
eat
lots
of
CPU } 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 95. @ThreadInterrupt @ThreadInterrupt import
groovy.transform.ThreadInterrupt
 
 while
(true)
{ { 



if
(Thread.currentThread.isInterrupted()) 







throw
new
InterruptedException() } 



//
eat
lots
of
CPU } • Two optional annotation parameters available – checkOnMethodStart (true by default) – applyToAllClasses (true by default) 33 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 96. @TimedInterrupt @TimedInterrupt(10) import
groovy.transform.TimedInterrupt
 
 while
(true)
{ 



//
eat
lots
of
CPU } • InterruptedException thrown when checks indicate code ran longer than desired • Optional annotation parameters available – same as @ThreadInterrupt – value: for an amount of time duration 34 – unit: for the time duration unit (TimeUnit.SECONDS) @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 97. @ConditionalInterrupt • Specify your own condition to be inserted at the start of method and closure bodies – check for available resources, number of times run, etc. • Leverages closure annotation parameters from Groovy 1.8 @ConditionalInterrupt({
counter++
>
2
}) import
groovy.transform.ConditionalInterrupt import
groovy.transform.Field
 
 @Field
int
counter
=
0
 100.times
{



 



println
'executing
script
method...' } 35 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 98. @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) 36 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 99. @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() 37 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 100. @TupleConstructor • Provides a «classical» constructor with all properties • Several annotation parameter options available import
groovy.transform.TupleConstructor
 
 @TupleConstructor
 class
Person
{



 



String
name



 



int
age }
 
 def
m
=
new
Person('Marion',
3)





 
 assert
m.name
==
'Marion' assert
m.age

==
3 38 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 101. @Canonical • One annotation to rule them all! – @Canonical mixes together • @ToString • @EqualsAndHashCode • @TupleConstructor • You can customize behavior by combining @Canonical and one of the other annotations 39 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 102. @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated class
CustomException
extends
Exception
{ 



CustomException()























{
super()






} 



CustomException(String
msg)













{
super(msg)



} 



CustomException(String
msg,
Throwable
t)
{
super(msg,
t)
} 



CustomException(Throwable
t)












{
super(t)





} } 40 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 103. @InheritConstructor • Classes like Exception are painful when extended, as all the base constructors should be replicated import
groovy.transform.* @InheritConstructors class
CustomException
extends
Exception
{ 



CustomException()























{
super()






} 



CustomException(String
msg)













{
super(msg)



} 



CustomException(String
msg,
Throwable
t)
{
super(msg,
t)
} 



CustomException(Throwable
t)












{
super(t)





} } 40 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 104. @WithReadLock, @WithWriteLock import
groovy.transform.*
 
 class
ResourceProvider
{



 



private
final
Map<String,
String>
data
=
new
HashMap<>() 
 



@WithReadLock



 



String
getResource(String
key)
{







 







return
data.get(key)



 



}




 
 



@WithWriteLock



 



void
refresh()
{







 







//reload
the
resources
into
memory



 



} } 41 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 105. @WithReadLock, @WithWriteLock import
groovy.transform.*
 
 class
ResourceProvider
{



 



private
final
Map<String,
String>
data
=
new
HashMap<>() 
 { 



@WithReadLock



 



String
getResource(String
key)
{







 







return
data.get(key)



 



}




 
 { 



@WithWriteLock



 



void
refresh()
{







 







//reload
the
resources
into
memory



 



} } 41 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 106. Miscelanous • Compilation customizers • Java 7 diamond operator • Slashy and dollar slashy strings • New GDK methods • (G)String to Enum coercion 42 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 107. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers – ImportCustomizer – SecureASTCustomizer – ASTTransformationCustomizer • But you can implement your own 43 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 108. Imports customizer def
configuration
=
new
CompilerConfiguration() 
 def
custo
=
new
ImportCustomizer() custo.addStaticStar(Math.name) configuration.addCompilationCustomizers(custo)
 
 def
result
=
new
GroovyShell(configuration) 



.evaluate("
cos
PI/3
") 44 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 109. Applying an AST transformation def
configuration
=
new
CompilerConfiguration() configuration.addCompilationCustomizers( 



new
ASTTransformationCustomizer(Log))
 
 new
GroovyShell(configuration).evaluate(""" 



class
Car
{







 







Car()
{











 











log.info
'Car
constructed'







 







}



 



}




 



log.info
'Constructing
a
car'



 



def
c
=
new
Car() """) 45 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 110. Secure AST customizer Idea: Implement an «arithmetic shell» Being able control what a user script is allowed to do: only arithmetic expressions • Let’s setup our environment – some imports – an import customizer to import java.lang.Math.* – prepare a secure AST customizer import
org.codehaus.groovy.control.customizers.* import
org.codehaus.groovy.control.* import
static
org.codehaus.groovy.syntax.Types.* 
 def
imports
=
new
ImportCustomizer().addStaticStars('java.lang.Math') def
secure
=
new
SecureASTCustomizer() 46 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 111. Secure AST customizer ... secure.with
{ //
disallow
closure
creation closuresAllowed
=
false
 //
disallow
method
definitions methodDefinitionAllowed
=
false
 
 //
empty
white
list
=>
forbid
imports importsWhitelist
=
[]
 staticImportsWhitelist
=
[] //
only
allow
the
java.lang.Math.*
static
import staticStarImportsWhitelist
=
['java.lang.Math' ... 47 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 112. Secure AST customizer ... //
language
tokens
allowed tokensWhitelist
=
[ PLUS,
MINUS,
MULTIPLY,
DIVIDE,
MOD,
POWER,
PLUS_PLUS,
 MINUS_MINUS,
COMPARE_EQUAL,
COMPARE_NOT_EQUAL,
 COMPARE_LESS_THAN,
COMPARE_LESS_THAN_EQUAL,
 COMPARE_GREATER_THAN,
COMPARE_GREATER_THAN_EQUAL ] 
 //
types
allowed
to
be
used
(including
primitive
types) constantTypesClassesWhiteList
=
[ Integer,
Float,
Long,
Double,
BigDecimal,
 Integer.TYPE,
Long.TYPE,
Float.TYPE,
Double.TYPE ] 
 //
classes
who
are
allowed
to
be
receivers
of
method
calls receiversClassesWhiteList
=
[
 Math,
Integer,
Float,
Double,
Long,
BigDecimal
] } ... 48 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 113. Secure AST customizer • Ready to evaluate our arithmetic expressions! ... def
config
=
new
CompilerConfiguration() config.addCompilationCustomizers(imports,
secure) def
shell
=
new
GroovyShell(config) 
 shell.evaluate
'cos
PI/3' • But the following would have failed: shell.evaluate
'System.exit(0)' 49 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 114. Slashy and dollar slashy strings • Slashy strings are now multiline – particularly handy for multi-line regexs • Dollar slashy string notation introduced def
(name,
date)
=
["Guillaume",
"Oct,
26th"] def
dollarSlashy
=
$/



 



Hello
$name,
today
we're
${date} 



$
dollar‐sign



 



$$
dollar‐sign



 




backslash



 



/
slash



 


$/
slash /$
 50 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 115. New GDK methods 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 116. New GDK methods //
count 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 117. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 118. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 119. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 120. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 121. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 122. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 123. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 124. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 125. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 126. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 127. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 
 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 128. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 
 //
map
withDefault() 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 129. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 
 //
map
withDefault() def
words
=
"one
two
two
three
three
three".split() 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 130. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 
 //
map
withDefault() def
words
=
"one
two
two
three
three
three".split() def
freq
=
[:].withDefault
{
k
‐>
0
} 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 131. New GDK methods //
count assert
[2,4,2,1,3,5,2,4,3].count
{
it
%
2
==
0
}
==
5 
 //
count
by assert
[0:2,
1:3]
==
[1,2,3,4,5].countBy{
it
%
2
} assert
[(true):2,
(false):4]
 



==
'Groovy'.toList().countBy{
it
==
'o'
} 
 //
min/max
for
maps
with
closures def
map
=
[a:
1,
bbb:
4,
cc:
5,
dddd:
2]
 assert
map.max
{
it.key.size()
}.key
==
'dddd' assert
map.min
{
it.value
}.value
==
1 
 //
map
withDefault() def
words
=
"one
two
two
three
three
three".split() def
freq
=
[:].withDefault
{
k
‐>
0
} words.each
{
freq[it]
+=
1
} 51 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 132. (G)String to Enum coercion 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 133. (G)String to Enum coercion enum
Color
{



 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 134. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 135. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 136. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 137. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 138. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 139. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 140. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 //
implicit
coercion 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 141. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 //
implicit
coercion Color
b
=
"blue"
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 142. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 //
implicit
coercion Color
b
=
"blue"
 
 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 143. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 //
implicit
coercion Color
b
=
"blue"
 
 //
with
GStrings
too 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 144. (G)String to Enum coercion enum
Color
{



 



red,
green,
blue }
 
 //
coercion
with
as def
r
=
"red"
as
Color
 
 //
implicit
coercion Color
b
=
"blue"
 
 //
with
GStrings
too def
g
=
"${'green'}"
as
Color 52 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 145. Customizing the Groovysh prompt 53 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 146. Launching remote scripts • With the Groovy command, you can launch remote scripts >
groovy
http://groovyconsole.appspot.com/raw/110001 • Be careful to what you’re executing :-) 54 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 148. Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Static type checking and compilation • Miscelanous • What else? Your call! 56 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 149. Groovy 1.9 roadmap • Java 7 alignements: Project Coin – binary literals – underscore in literals – multicatch • JDK 7: InvokeDynamic • Towards a more modular Groovy • Static type checking and compilation • Miscelanous • What else? Your call! 56 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 150. Java 7 / JDK 7 • Project Coin and InvokeDynamic 57 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 151. Binary literals • We had decimal, octal and hexadecimal notations for number literals int
x
=
0b10101111 assert
x
==
175 
 byte
aByte
=
0b00100001 assert
aByte
==
33 
 int
anInt
=
0b1010000101000101 assert
anInt
==
41285 58 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 152. 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 59 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 153. Multicatch • One block for multiple exception caught – rather than duplicating the block try
{ 



/*
...
*/ }
catch(IOException
|
NullPointerException
e)
{ 



/*
one
block
to
treat
2
exceptions
*/ } 60 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 154. InvokeDynamic • Groovy 1.9 will support JDK 7ʼs invokeDynamic – an «indy» branch started recently – compiler will have a flag for compiling against JDK 7 • Benefits – more runtime performance! – in the long run, will allow us to get rid of code! • call site caching, thanks to MethodHandles • metaclass registry, thanks to ClassValues • will let the JIT inline calls more easily 61 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 155. Groovy Modularity • Groovy’s «all» JAR weighs in at 4MB • Nobody needs everything – Template engine, Ant scripting, Swing UI building... • Provide a smaller core – and several smaller JARs per feature • Paul King covers Groovy modularisation – Wednesday, 12:45-2:15PM 62 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 156. 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 63 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 157. A typo in your variable or method names import
groovy.transform.StaticTypes 
 void
method()
{} 
 @TypeChecked
test()
{ 



//
Cannot
find
matching
method
metthhoood() 



metthhoood() 
 



def
name
=
"Guillaume" 



//
variable
naamme
is
undeclared 



println
naamme } 64 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 158. A typo in your variable or method names import
groovy.transform.StaticTypes 
 void
method()
{} 
 @TypeChecked
test()
{ 



//
Cannot
find
matching
method
metthhoood() 



metthhoood() 
 



def
name
=
"Guillaume" 



//
variable
naamme
is
undeclared Compilation 



println
naamme errors! } 64 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 159. Complain on wrong assignments //
cannot
assign
value
of
type...
to
variable... int
x
=
new
Object() Set
set
=
new
Object() 
 def
o
=
new
Object() int
x
=
o 
 String[]
strings
=
['a','b','c'] int
str
=
strings[0] 
 //
cannot
find
matching
method
plus() int
i
=
0 i
+=
'1' 65 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 160. Complain on wrong assignments //
cannot
assign
value
of
type...
to
variable... int
x
=
new
Object() Set
set
=
new
Object() Compilation 
 errors! def
o
=
new
Object() int
x
=
o 
 String[]
strings
=
['a','b','c'] int
str
=
strings[0] 
 //
cannot
find
matching
method
plus() int
i
=
0 i
+=
'1' 65 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 161. Complain on wrong return types String
method()
{
'String'
} //
cannot
assign
value
of
type
String... int
x
=
method() //
checks
if/else
branch
return
values int
method()
{ 



if
(true)
{
'String'
} 



else
{
42
} } //
works
for
switch/case
&
try/catch/finally 
 //
transparent
toString()
implied String
greeting(String
name)
{ 



def
sb
=
new
StringBuilder() 



sb
<<
"Hi"
<<
name } 66 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 162. Complain on wrong return types String
method()
{
'String'
} //
cannot
assign
value
of
type
String... int
x
=
method() Compilation errors! //
checks
if/else
branch
return
values int
method()
{ 



if
(true)
{
'String'
} 



else
{
42
} } //
works
for
switch/case
&
try/catch/finally 
 //
transparent
toString()
implied String
greeting(String
name)
{ 



def
sb
=
new
StringBuilder() 



sb
<<
"Hi"
<<
name } 66 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 163. 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 



} } 67 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 164. Staticly checked method & dynamic method @TypeChecked String
greeting(String
name)
{ 



//
call
method
with
dynamic
behavior 



//
but
with
proper
signature 



generateMarkup(name.toUpperCase()) } 
 //
usual
dynamic
behavior String
generateMarkup(String
name)
{ 



def
sw
=
new
StringWriter() 



new
MarkupBuilder(sw).html
{ 







body
{ 











div
name 







} 



} 



sw.toString() } 68 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 165. Bytecode viewer • Groovy Console’s bytecode viewer from the AST browser window – select class generation phase – select a class node 69 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 166. Disable Global AST transformations //
witout
a
specific
configuration,
the
AST
builder
works def
shell
=
new
GroovyShell() shell.evaluate(script)
//
passes def
config
=
new
CompilerConfiguration() config.disabledGlobalASTTransformations
= 



['org.codehaus.groovy.ast.builder.AstBuilderTransformation'] def
script
=
''' 



import
org.codehaus.groovy.ast.builder.AstBuilder 



new
AstBuilder().buildFromCode
{
"Hello"
} ''' 
 //
now
with
the
configuration
in
place, //
the
AST
builder
transform
is
not
applied shell
=
new
GroovyShell(config)
//
<‐‐
with
the
configuration shouldFail
{ 



shell.evaluate(script)
//
fails } 70 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 167. Summary 71 @glaforge — http://glaforge.appspot.com — ROCKS! http://gplus.to/glaforge
  • 168. Thank you! e L aforg pment aume vy Develo Guill Groo m Hea d of g mail.co aforge@ mail: gl glaforge e E @ o /glaforg T witter : http://gplus.t Go ogle+: 72 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge
  • 169. Q&A — Got questions, Really? 73 © 2011 SpringOne 2GX 2011. All rights reserved. Do not distribute without permission.
  • 170. Image credits • Iceberg: http://hqworld.net/gallery/data/media/20/tip_of_the_iceberg.jpg • Bicycle: http://drunkcyclist.com/gallery/main.php?g2_view=core.DownloadItem&g2_itemId=2131&g2_serialNumber=2 • Pills: http://www.we-ew.com/wp-content/uploads/2011/01/plan-b-pills.jpg • Chains: http://2.bp.blogspot.com/-GXDVqUYSCa0/TVdBsON4tdI/AAAAAAAAAW4/EgJOUmAxB28/s1600/breaking-chains5_copy9611.jpg • Cooking: http://www.flickr.com/photos/eole/449958332/sizes/l/ • Oui nide iou: http://desencyclopedie.wikia.com/wiki/Fichier:Superdupont_we_need_you.jpg • Guitar: http://www.lelitteraire.com/IMG/breveon323.jpg • Trampoline: http://www.fitness-online.fr/images/trampoline-1-m.jpg • Curry: http://www.pot-a-epices.com/wp-content/uploads/2009/02/curry1.jpg • Slurp: http://www.ohpacha.com/218-532-thickbox/gamelle-slurp.jpg • Caution: http://www.jeunes-epinay-sur-seine.fr/wp-content/uploads/2010/11/caution-colocation.jpg • Grumpy: http://mafeuilledechou.fr/__oneclick_uploads/2010/05/grumpy.jpg • Modularity: http://php.jglobal.com/blog/wp-content/uploads/2009/11/modularity.jpg • Agenda: http://www.plombiereslesbains.fr/images/stories/agenda.jpg • Java 7: http://geeknizer.com/wp-content/uploads/java7.jpg • WIP: http://www.connetport.com/wp-content/uploads/Work_in_progress.svg_.png • Grumpy 2: http://grumpy.division-par-zero.fr/wp-content/images/grumpy.jpg • 74 @glaforge — http://glaforge.appspot.com — http://gplus.to/glaforge

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. \n
  80. \n
  81. \n
  82. \n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. \n
  102. \n
  103. \n
  104. \n
  105. \n
  106. \n
  107. \n
  108. \n
  109. \n
  110. \n
  111. \n
  112. \n
  113. \n
  114. \n
  115. \n
  116. \n
  117. \n
  118. \n
  119. \n
  120. \n
  121. \n
  122. \n
  123. \n
  124. \n
  125. \n
  126. \n
  127. \n
  128. \n
  129. \n
  130. \n
  131. \n
  132. \n
  133. \n
  134. \n
  135. \n
  136. \n
  137. \n
  138. \n
  139. \n
  140. \n
  141. \n
  142. \n
  143. \n
  144. \n
  145. \n
  146. \n
  147. \n
  148. \n
  149. \n
  150. \n
  151. \n
  152. \n
  153. \n
  154. \n
  155. \n
  156. \n
  157. \n
  158. \n
  159. \n
  160. \n
  161. \n
  162. \n
  163. \n
  164. \n
  165. \n
  166. \n
  167. \n
  168. \n
  169. \n
  170. \n
  171. \n
  172. \n
  173. \n
  174. \n
  175. \n
  176. \n
  177. \n
  178. \n
  179. \n
  180. \n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n
  187. \n
  188. \n
  189. \n