SlideShare a Scribd company logo
Groovy
Domain
Specific    Guillaume Laforge
            Groovy Project Manager
            SpringSource / VMware
Languages          @glaforge




                                     1
ГИЙОМ
ЛАФОРЖ
Guillaume Laforge

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

•   Co-author of Groovy in Action


•   Follow me on...
    •My blog: http://glaforge.appspot.com
    •Twitter: @glaforge
    •Google+: http://gplus.to/glaforge
                                            3
Introduction
Definition, Examples, Goals, Pros & Cons




                                          4
Domain-Specific Languages

    •   Wikipedia definition




{                                                                }
        A Domain-Specific Language is a programming
        language or executable specification language that
        offers, through appropriate notations and
        abstractions, expressive power focused on, and usually
        restricted to, a particular problem domain.


    •   In contrast to General Purprose Languages
    •   Also known as: fluent / human interfaces, language oriented programming,
        little or mini languages, macros, business natural languages...


                                                                                  5
Technical examples
Glade                                     XSLT
<?xml version="1.0"?>                      <?xml version="1.0"?>
<GTK-Interface>                            <xsl:stylesheetversion="1.0"
<widget>                                       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <class>GtkWindow</class>                 <xsl:output method="xml"/>
  <name>HelloWindow</name>                   <xsl:template match="*">
  <border_width>5</border_width>
  <Signal>
                                               <xsl:element name="{name()}">                               Regex
                                                 <xsl:for-each select="@*">
    <name>destroy</name>
    <handler>gtk_main_quit</handler>
                                                   <xsl:element name="{name()}">
                                                     <xsl:value-of select="."/>
                                                                                                               "x.z?z{1,3}y"
  </Signal>
  <title>Hello</title>                             </xsl:element>
  <type>GTK_WINDOW_TOPLEVEL</type>               </xsl:for-each>
  <position>GTK_WIN_POS_NONE</position>          <xsl:apply-templates select="*|text()"/>
  <allow_shrink>True</allow_shrink>            </xsl:element>
  <allow_grow>True</allow_grow>              </xsl:template>
  <auto_shrink>False</auto_shrink>         </xsl:stylesheet>
  <widget>
    <class>GtkButton</class>
    <name>Hello World</name>
    <can_focus>True</can_focus>
                                                           fetchmail
    <label>Hello World</label>
                                                             # Poll this site first each cycle.
  </widget>                                                  poll pop.provider.net proto pop3
</widget>                                                      user "jsmith" with pass "secret1" is "smith" here
</GTK-Interface>                                               user jones with pass "secret2" is "jjones" here with options keep

                   SQL                                       # Poll this site second, unless Lord Voldemort zaps us first.
                                                             poll billywig.hogwarts.com with proto imap:
                                                               user harry_potter with pass "floo" is harry_potter here
                   SELECT * FROM TABLE
                                                             # Poll this site third in the cycle.
                   WHERE NAME LIKE '%SMI'                    # Password will be fetched from ~/.netrc
                   ORDER BY NAME                             poll mailhost.net with proto imap:
                                                               user esr is esr here
Antimalaria drug             Insurance policy risk        HR skills representation
resistance simulation        calculation engine




                                                           Nuclear safety simulations




Market data feeds analysis                       Loan acceptance rules engine
Goals of DSLs

•   Use a more expressive language than a general-purpose one

•   Share a common metaphor of understanding
    between developers and subject matter experts

•   Have domain experts help with the design
    of the business logic of an application

•   Avoid cluttering business code with too much boilerplate technical code
    thanks to a clean separation

•   Let business rules have their own lifecycle



                                                                              8
Pros and cons

 Pros                                             Cons
 •   Domain experts can help, validate,           •   Learning cost vs. limited applicability
     modify, and often develop DSL
     programs
                                                  •   Cost of designing, implementing &
                                                      maintaining DSLs as well as tools/IDEs
 •   Somewhat self-documenting
                                                  •   Attaining proper scope
 •   Enhance quality, productivity,
                                                  •   Trade-offs between domain specificity
     reliability, maintainability, portability,       and general purpose language
     reusability                                      constructs
 •   Safety; as long as the language
                                                  •   Efficiency cost
     constructs are safe, any DSL
     sentence can be considered safe              •   Proliferation of similar
                                                      non-standard DSLs

                                                                                                9
Groovy provides...

•   A flexible and malleable syntax
    •scripts, native syntax constructs (list, map, ranges), closures, less punctuation...


•   Compile-time and runtime meta-programming
    •metaclasses, AST transformations
    •also operator overloading


•   The ability to easily integrate into Java / Spring apps
    •also security and safety


                                                                                            10
Let’s get started!




                     11
Your mission:   build a DSL for
                  a Mars robot
We need a robot!
 class!Robot!{}




                   14
It should move...
 class!Robot!{
 !!!!void)move()!{}
 }




                      15
..in a direction!
 class!Robot!{
 !!!!void)move(String!dir)!{}
 }




                                16
More explicit direction
 class!Robot!{
 !!!!void)move(Direction!dir)!{}
 }




 enum!Direction!{
 !!!!left,!right,!forward,!backward
 }


                                      17
Now how can we control it?

import)static)mars.Direction.*;
import)mars.Robot;

public)class)Command!{
))))public)static)void)main(String[]!args)!{
!!!!!!!!Robot!robot!=)new!Robot();
!!!!!!!!robot.move(left);
!!!!}
}


                                               18
Now how can we control it?

import)static)mars.Direction.*;
import)mars.Robot;

public)class)Command!{
))))public)static)void)main(String[]!args)!{
!!!!!!!!Robot!robot!=)new!Robot();
!!!!!!!!robot.move(left);
!!!!}
}                    Syntactical
                      noise!

                                               18
Now how can we control it?

))))))))))))))))))))))))))))))—
import)static)mars.Direction.*;
)))))))))))))))))—
import)mars.Robot;

——————————————————————
public)class)Command!{
))))————————————————————————————————————————
))))public)static)void)main(String[]!args)!{
))))))))—————))))))))))))))))))))—
!!!!!!!!Robot!robot!=)new!Robot();
))))))))))))))))))—))))——
!!!!!!!!robot.move(left);
))))—
!!!!}
—
}                    Syntactical
                      noise!

                                               18
Scripts vs Classes
Optional semicolons & parens
import)static)mars.Direction.*
import)mars.Robot



!!!!!!!!def))!robot!=)new!Robot()
!!!!!!!!robot.move!left




                                    19
Scripts vs Classes
Optional semicolons & parens
import)static)mars.Direction.*
import)mars.Robot

                Optional typing

!!!!!!!!def))!robot!=)new!Robot()
!!!!!!!!robot.move!left




                                    19
Scripts vs Classes
Optional semicolons & parens
import)static)mars.Direction.*
import)mars.Robot

                   Optional typing

!!!!!!!!def))!robot!=)new!Robot()
!!!!!!!!robot.move!left

          But I don’t want to
          compile a script for
           every command!
                                     19
Integration
GroovyShell to the rescue




                            21
GroovyShell to the rescue
                 def$shell%=$new%GroovyShell()
                 shell.evaluate(
                 %%%%new%File("command.groovy")
                 )




                                                  21
GroovyShell to the rescue
                       def$shell%=$new%GroovyShell()
                       shell.evaluate(
  integration.groovy   %%%%new%File("command.groovy")
                       )




                                                        21
GroovyShell to the rescue
                        def$shell%=$new%GroovyShell()
                        shell.evaluate(
   integration.groovy   %%%%new%File("command.groovy")
                        )


import$static$mars.Direction.*
import$mars.Robot

def$robot%=$new%Robot()
robot.move%left
                                                         21
GroovyShell to the rescue
                        def$shell%=$new%GroovyShell()
                        shell.evaluate(
   integration.groovy   %%%%new%File("command.groovy")
                        )


import$static$mars.Direction.*
import$mars.Robot
                                        command.groovy
def$robot%=$new%Robot()
robot.move%left
                                                         21
Integration mechanisms

•   Different solutions available:
    •Groovy’s own mechanisms
     •  GroovyScriptEngine, Eval,
        GroovyClassLoader, GroovyShell
    •Java 6: javax.script.* / JSR-223
        •
        Groovy provides a JSR-223 implementation
    •Spring’s lang namespace


•   Groovy provides the highest level of flexibility
    and customization, but JSR-223 is a standard...


                                                      22
Integration mechanisms

•   Different solutions available:
    •Groovy’s own mechanisms
     •  GroovyScriptEngine, Eval,
        GroovyClassLoader, GroovyShell
    •Java 6: javax.script.* / JSR-223
        •
        Groovy provides a JSR-223 implementation
    •Spring’s lang namespace


•   Groovy provides the highest level of flexibility
    and customization, but JSR-223 is a standard...


                                                      22
What’s wrong with our DSL?


       import)static)mars.Direction.*
       import)mars.Robot

       def)robot!=)new!Robot()
       robot.move!left




                                        23
What’s wrong with our DSL?
       Can’t we hide
      those imports?

       import)static)mars.Direction.*
       import)mars.Robot

       def)robot!=)new!Robot()
       robot.move!left




                                        23
What’s wrong with our DSL?
       Can’t we hide
      those imports?

       import)static)mars.Direction.*
       import)mars.Robot

       def)robot!=)new!Robot()
       robot.move!left
                                   Can’t we inject
                                     the robot?

                                                     23
What’s wrong with our DSL?
        Can’t we hide
       those imports?

         import)static)mars.Direction.*
         import)mars.Robot

         def)robot!=)new!Robot()
         robot.move!left
                                     Can’t we inject
    Do we really need to               the robot?
      repeat ‘robot’?
                                                       23
I’m sorry Dave,
you can’t do that!
I’m sorry Dave,
you can’t do that!
What we really want is...



                !move!left!




                              25
Let’s inject a robot!

•   We can pass data in / out of scripts through the Binding
    •it’s basically just like a map of variable name keys and their associated values




                                                                                        26
Let’s inject a robot!

•   We can pass data in / out of scripts through the Binding
    •it’s basically just like a map of variable name keys and their associated values


           def)binding!=)new!Binding([
           !!!!robot:!new!Robot()
           ])
           def)shell!=)new!GroovyShell(binding)
           shell.evaluate(
           !!!!new!File("command.groovy")
           )

                                                                                        26
Let’s inject a robot!

•   We can pass data in / out of scripts through the Binding
    •it’s basically just like a map of variable name keys and their associated values

                                                               integration.groovy
           def)binding!=)new!Binding([
           !!!!robot:!new!Robot()
           ])
           def)shell!=)new!GroovyShell(binding)
           shell.evaluate(
           !!!!new!File("command.groovy")
           )

                                                                                        26
Better?


      import)static)mars.Direction.*



      robot.move!left




                                       27
Better?
Robot import
  removed
               import)static)mars.Direction.*



               robot.move!left




                                                27
Better?
Robot import
  removed
               import)static)mars.Direction.*



               robot.move!left

                                     Robot injected,
                                    no ‘new’ needed

                                                       27
How to inject the direction?

•   Using the binding...
                  def)binding!=)new!Binding([
                  !!!!robot:!new!Robot(),
                  !!!!left:!!!!!Direction.left,
                  !!!!right:!!!!Direction.right,
                  !!!!backward:!Direction.backward,
                  !!!!forward:!!Direction.forward
                  ])
                  def)shell!=)new!GroovyShell(binding)
                  shell.evaluate(
                  !!!!new!File("command.groovy")
                  )
                                                         28
How to inject the direction?
                                                Fragile in case of
                                                 new directions!
•   Using the binding...
                  def)binding!=)new!Binding([
                  !!!!robot:!new!Robot(),
                  !!!!left:!!!!!Direction.left,
                  !!!!right:!!!!Direction.right,
                  !!!!backward:!Direction.backward,
                  !!!!forward:!!Direction.forward
                  ])
                  def)shell!=)new!GroovyShell(binding)
                  shell.evaluate(
                  !!!!new!File("command.groovy")
                  )
                                                                     28
How to inject the direction?

•   Using the binding...
                  def)binding!=)new!Binding([
                  !!!!robot:!new!Robot(),
                  !!!!*:!Direction.values()
                  !!!!!!!!!!!!.collectEntries!{
                  !!!!!!!!!!!!!!!![(it.name()):!it]
                  !!!!!!!!!!!!}
                  ])
                  def)shell!=)new!GroovyShell(binding)
                  shell.evaluate(
                  !!!!new!File("command.groovy")
                  )
                                                         29
How to inject the direction?

•   Using compiler customizers...


•   Let’s have a look at them




                                    30
Compilation customizers

•   Ability to apply some customization
    to the Groovy compilation process


•   Three available customizers
    •ImportCustomizer: add transparent imports
    •ASTTransformationCustomizer: injects an AST transform
    •SecureASTCustomizer: restrict the groovy language to an allowed subset


•   But you can implement your own



                                                                              31
Imports customizer




 new!GroovyShell(new!Binding([robot:!new)Robot()]))
 !!!!.evaluate("import!static!Direction.*n"!+
 !!!!!!!!!!!!!!"robot.move!left")



                                                      32
Imports customizer

                                  Cheat with string
                                concatenation? Bad!



 new!GroovyShell(new!Binding([robot:!new)Robot()]))
 !!!!.evaluate("import!static!Direction.*n"!+
 !!!!!!!!!!!!!!"robot.move!left")



                                                      32
Imports customizer




 new!GroovyShell(new!Binding([robot:!new)Robot()]))
 !!!!.evaluate("import!static!Direction.*n"!+
 !!!!!!!!!!!!!!"robot.move!left")



                                                      32
Imports customizer
 def!configuration!=!new!CompilerConfiguration()
 !
 def!imports!=!new!ImportCustomizer()
 imports.addStaticStar(mars.Direction.name)
 configuration.addCompilationCustomizers(imports)!
 !

 new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!!
                                                         !
 !!!!!!!!!!!!!!!!configuration)
 !!!!.evaluate("robot.move!left")!!!!!!



                                                         33
AST transformation customizer
 def!configuration!=!new!CompilerConfiguration()
 !
 def!imports!=!new!ImportCustomizer()
 imports.addStaticStar(mars.Direction.name)
 configuration.addCompilationCustomizers(imports,
 !!!!!!!!!!!!!new!ASTTransformationCustomizer(Log))
 !
 new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!!
                                                         !
 !!!!!!!!!!!!!!!!configuration)
 !!!!.evaluate("robot.move!left"!+!"n"
 !!!!!!!!!!!!!!"log.info!‘Robot!moved’")!!!!!!!!!!!


                                                         34
AST transformation customizer
    def!configuration!=!new!CompilerConfiguration()
    !
    def!imports!=!new!ImportCustomizer()
    imports.addStaticStar(mars.Direction.name)
    configuration.addCompilationCustomizers(imports,
    !!!!!!!!!!!!!new!ASTTransformationCustomizer(Log))
    !
    new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!!
                                                            !
    !!!!!!!!!!!!!!!!configuration)
    !!!!.evaluate("robot.move!left"!+!"n"
    !!!!!!!!!!!!!!"log.info!‘Robot!moved’")!!!!!!!!!!!
@Log injects a logger in
  scripts and classes
                                                            34
Secure the onboard
trajectory calculator
Secure AST customizer
                       Idea: Secure the rocket’s onboard trajectory
                       calculation system by allowing only math
                       expressions to be evaluated by the calculator



•   Let’s setup our environment
    •an import customizer to import java.lang.Math.*
    •prepare a secure AST customizer

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



                                                                        36
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']
...

                                                     37
Secure AST customizer
                                  Disallow closures
...                                 and methods
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']
...

                                                      37
Secure AST customizer
                                     Disallow closures
...                                    and methods
secure.with!{
  //!disallow!closure!creation
  closuresAllowed!=!false!
  //!disallow!method!definitions          Black / white list
  methodDefinitionAllowed!=!false!
                                              imports
!
  //!empty!white!list!=>!forbid!imports
  importsWhitelist!=![]!
  staticImportsWhitelist!=![]
  //!only!allow!the!java.lang.Math.*!static!import
  staticStarImportsWhitelist!=!['java.lang.Math']
...

                                                               37
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%]
}
...
                                                                                       38
Secure AST customizer                          You can build a subset of
                                                  the Groovy syntax!
...
   //%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%]
}
...
                                                                                       38
Secure AST customizer                          You can build a subset of
                                                  the Groovy syntax!
...
   //%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)
                                                                 Black / white list
   constantTypesClassesWhiteList%=%[                             usage of classes
      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%]
}
...
                                                                                       38
Secure AST customizer

•   Ready to evaluate our flight equations!
           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)'

                                                               39
Back to our robot...




            robot.move)left



                              40
Back to our robot...


              Still need to get rid
              of the robot prefix!


            robot.move)left



                                      40
Can we remove it?
Can we remove it?


                    да !
How to remove the ‘robot’?

•   Instead of calling the move() method on the robot
    instance, we should be able to call the move() method
    directly from within the script


•   Two approaches:


    •   Inject a ‘move’ closure in the         •   Use a base script class with a
                                                   ‘move’ method delegating to the
        binding with a method pointer
                                                   robot




                                                                                     42
Inject a closure in the binding
      def$robot%=%new%Robot()
      binding%=$new%Binding([
      %%%%robot:%robot,
      %%%%*:%Direction.values()
      %%%%%%%%%%%%.collectEntries%{
      %%%%%%%%%%%%%%%%[(it.name()):%it]
      %%%%%%%%%%%%},

      %%%%move:%robot.&move
      ])


                                          43
Inject a closure in the binding
      def$robot%=%new%Robot()
      binding%=$new%Binding([
      %%%%robot:%robot,
      %%%%*:%Direction.values()
      %%%%%%%%%%%%.collectEntries%{
      %%%%%%%%%%%%%%%%[(it.name()):%it]
      %%%%%%%%%%%%},

      %%%%move:%robot.&move
      ])
                              Method pointer (a closure) on
                              robot’s move instance method
                                                              43
Define a base script class

       abstract)class!RobotBaseScriptClass!!!
       !!!!!!!extends!Script!{
       !!!!void!move(Direction!dir)!{
       !!!!!!!!def)robot!=!this.binding.robot
       !!!!!!!!robot.move!dir
       !!!!}
       }




                                                44
Define a base script class

            abstract)class!RobotBaseScriptClass!!!
            !!!!!!!extends!Script!{
            !!!!void!move(Direction!dir)!{
            !!!!!!!!def)robot!=!this.binding.robot
            !!!!!!!!robot.move!dir
            !!!!}
            }


The move() method is
now at the script level

                                                     44
Define a base script class

            abstract)class!RobotBaseScriptClass!!!
            !!!!!!!extends!Script!{
            !!!!void!move(Direction!dir)!{
            !!!!!!!!def)robot!=!this.binding.robot
            !!!!!!!!robot.move!dir
            !!!!}
            }


The move() method is                    Access the robot through
now at the script level                   the script’s binding

                                                                   44
Configure the base script class

def)conf)=)new)CompilerConfiguration()
conf.scriptBaseClass)=)RobotBaseScriptClass




                                              45
Configure the base script class

def)conf)=)new)CompilerConfiguration()
conf.scriptBaseClass)=)RobotBaseScriptClass


                  Scripts evaluated with
                  this configuration will
                  inherit from that class



                                              45
Ready for lift off!

   %%move%left
Beep, beep...
yes but how do you
 define the speed?
     ...beep...
Oh no!
What we could do now is...




         move!left,!at:!3.km/h




                                 49
What we could do now is...

                 Mix of named and
                normal parameters



         move!left,!at:!3.km/h




                                    49
What we could do now is...

                 Mix of named and
                normal parameters



         move!left,!at:!3.km/h

                                How to add a km
                              property to numbers?


                                                     49
Adding properties to numbers

•   We need to:


    •   define units, distance and speed


    •   have a nice notation for them
        • that’s where we add properties to numbers!




                                                       50
Unit enum and Distance class
enum$DistanceUnit%{
%%%%centimeter%('cm',%%%%0.01),
%%%%meter%%%%%%(%'m',%%%%1),%
%%%%kilometer%%('km',%1000)%
%%%%
%%%%String%abbreviation
%%%%double%multiplier
%%%%
%%%%Unit(String%abbr,%double%mult)%{
%%%%%%%%this.abbreviation%=%abbr
%%%%%%%%this.multiplier%=%mult%
%%%%}

%%%%String%toString()%{%abbreviation%}%
}
                                          51
Unit enum and Distance class
                                          @TupleConstructor%
enum$DistanceUnit%{                       class%Distance%{
%%%%centimeter%('cm',%%%%0.01),           %%%%double%amount%
%%%%meter%%%%%%(%'m',%%%%1),%             %%%%DistanceUnit%unit
%%%%kilometer%%('km',%1000)%
%%%%                                      %%%%String%toString()%{%
%%%%String%abbreviation                   %%%%%%%%"$amount%$unit"%
%%%%double%multiplier                     %%%%}%
%%%%                                      }
%%%%Unit(String%abbr,%double%mult)%{
%%%%%%%%this.abbreviation%=%abbr
%%%%%%%%this.multiplier%=%mult%
%%%%}

%%%%String%toString()%{%abbreviation%}%
}
                                                                     51
Different techniques

•   To add dynamic methods or properties,
    there are several approaches at your disposal:
    • ExpandoMetaClass
    • custom MetaClass
    • Categories


•   Let’s have a look at the ExpandoMetaClass




                                                     52
Using ExpandoMetaClass


   Number.metaClass.getCm%=%{%f>%
   %%%%new%Distance(delegate,%Unit.centimeter)%
   }
   Number.metaClass.getM%=%{%f>%
   %%%%new%Distance(delegate,%Unit.meter)%
   }
   Number.metaClass.getKm%=%{%f>%
   %%%%new%Distance(delegate,%Unit.kilometer)%
   }




                                                  53
Using ExpandoMetaClass
    Add that to
integration.groovy

       Number.metaClass.getCm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.centimeter)%
       }
       Number.metaClass.getM%=%{%f>%
       %%%%new%Distance(delegate,%Unit.meter)%
       }
       Number.metaClass.getKm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.kilometer)%
       }




                                                      53
Using ExpandoMetaClass
    Add that to
integration.groovy

       Number.metaClass.getCm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.centimeter)%
       }
       Number.metaClass.getM%=%{%f>%
       %%%%new%Distance(delegate,%Unit.meter)%
       }
       Number.metaClass.getKm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.kilometer)%
       }

                 ‘delegate’ is the
                  current number
                                                      53
Using ExpandoMetaClass
    Add that to
integration.groovy                                     Usage in
                                                      your DSLs
       Number.metaClass.getCm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.centimeter)%
       }                                                40.cm!
       Number.metaClass.getM%=%{%f>%
       %%%%new%Distance(delegate,%Unit.meter)%
                                                        3.5.m
       }                                                4.km
       Number.metaClass.getKm%=%{%f>%
       %%%%new%Distance(delegate,%Unit.kilometer)%
       }

                 ‘delegate’ is the
                  current number
                                                                  53
Distance okay, but speed?

•   For distance, we just added a property access after the number,
    but we now need to divide (‘div’) by the time




                                2.km/h


                                                                      54
Distance okay, but speed?

•   For distance, we just added a property access after the number,
    but we now need to divide (‘div’) by the time

                              The div() method
                                 on Distance


                                2.km/h


                                                                      54
Distance okay, but speed?

•   For distance, we just added a property access after the number,
    but we now need to divide (‘div’) by the time

                              The div() method
                                 on Distance


                                2.km/h
                                                An h duration
                                           instance in the binding
                                                                      54
First, let’s look at time
enum$TimeUnit%{
%%%%hour%%%%%%('h',%%%3600),
%%%%minute%%%%('min',%%%60),%
%%%%kilometer%('s',%%%%%%1)%
%%%%
%%%%String%abbreviation
%%%%double%multiplier
%%%%
%%%%TimeUnit(String%abbr,%double%mult)%{
%%%%%%%%this.abbreviation%=%abbr
%%%%%%%%this.multiplier%=%mult%
%%%%}

%%%%String%toString()%{%abbreviation%}%
}
                                           55
First, let’s look at time                 @TupleConstructor%
                                          class%Duration%{
enum$TimeUnit%{                           %%%%double%amount%
%%%%hour%%%%%%('h',%%%3600),              %%%%TimeUnit%unit
%%%%minute%%%%('min',%%%60),%
%%%%kilometer%('s',%%%%%%1)%             %%%%String%toString()%{%
%%%%                                     %%%%%%%%"$amount%$unit"%
%%%%String%abbreviation                  %%%%}%
%%%%double%multiplier                    }
%%%%
%%%%TimeUnit(String%abbr,%double%mult)%{
%%%%%%%%this.abbreviation%=%abbr
%%%%%%%%this.multiplier%=%mult%
%%%%}

%%%%String%toString()%{%abbreviation%}%
}
                                                                    55
Inject the ‘h’ hour constant in the binding

       def)binding!=)new!Binding([
       !!!!robot:!new!Robot(),
       !!!!*:!Direction.values()
       !!!!!!!!!!!!.collectEntries!{
       !!!!!!!!!!!!!!!![(it.name()):!it]
       !!!!!!!!!!!!},

       !!!!h:!new!Duration(1,!TimeUnit.hour)
       ])


                                               56
Now at (light!) speed
       @TupleConstructor)
       class)Speed){
       ))))Distance)distance
       ))))Duration)duration

       ))))String)toString()){)
       ))))))))"$distance/$duration")
       ))))})
       }

                                        57
Operator overloading
 a%+%b%%//%a.plus(b)
 a%f%b%%//%a.minus(b)          •       Currency amounts
 a%*%b%%//%a.multiply(b)           •    15.euros + 10.dollars
 a%/%b%%//%a.div(b)
 a%%%b%%//%a.modulo(b)         •       Distance handling
 a%**%b%//%a.power(b)              •    10.km - 10.m
 a%|%b%%//%a.or(b)
 a%&%b%%//%a.and(b)            •       Workflow, concurrency
 a%^%b%%//%a.xor(b)                •    taskA | taskB & taskC
 a[b]%%%//%a.getAt(b)
 a%<<%b%//%a.leftShift(b)      •       Credit an account
 a%>>%b%//%a.rightShift(b)
 +a%%%%%//%a.unaryPlus()
                                   • account    << 10.dollars
                                        account += 10.dollars
 fa%%%%%//%a.unaryMinus()               account.credit 10.dollars
 ~a%%%%%//%a.bitwiseNegate()

                                                                    58
Operator overloading

•   Update the Distance class with a div() method
    following the naming convetion for operators

                     class%Distance%{
                     %%%%...
                     %%%%Speed%div(Duration%t)%{
                     %%%%%%%%new%Speed(this,%t)
                     %%%%}
                     %%%%...
                     }


                                                    59
Operator overloading

•   Update the Distance class with a div() method
    following the naming convetion for operators

                     class%Distance%{
                     %%%%...
                     %%%%Speed%div(Duration%t)%{
                     %%%%%%%%new%Speed(this,%t)
                     %%%%}
                     %%%%...
                     }       Optional return


                                                    59
Equivalence of notation

•   Those two notations are actually equivalent:



                                2.km/h



                       2.getKm().div(h)

                                                   60
Equivalence of notation

•   Those two notations are actually equivalent:



                                2.km/h
                                                      This one might be
                                                   slightly more verbose!


                       2.getKm().div(h)

                                                                            60
Named parameters usage
       move!left,!at:!3.km/h




                               61
Named parameters usage
       move!left,!at:!3.km/h

          Normal
         parameter




                               61
Named parameters usage
       move!left,!at:!3.km/h

          Normal          Named
         parameter       parameter




                                     61
Named parameters usage
       move!left,!at:!3.km/h

             Normal              Named
            parameter           parameter
     Will call:
     def!take(Map!m,!Direction!q)




                                            61
Named parameters usage
          move!left,!at:!3.km/h

               Normal              Named
              parameter           parameter
       Will call:
       def!take(Map!m,!Direction!q)

  All named parameters go
   into the map argument
                                              61
Named parameters usage
          move!left,!at:!3.km/h

               Normal              Named
              parameter           parameter
       Will call:
       def!take(Map!m,!Direction!q)

  All named parameters go      Positional parameters
   into the map argument         come afterwards
                                                       61
Named parameters usage
       move!left,!at:!3.km/h




                               62
Named parameters usage
        move!left,!at:!3.km/h

      Can we get rid of
        the comma?




                                62
Named parameters usage
        move!left,!at:!3.km/h

      Can we get rid of   What about the
        the comma?          colon too?




                                           62
Command chains

•   A grammar improvement in Groovy 1.8 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)




                                                                 63
Command chains




       %move%left%%at%3.km/h%




                                64
Command chains
       Alternation of
       method names



       %move%left%%at%3.km/h%




                                64
Command chains
       Alternation of
       method names



       %move%left%%at%3.km/h%


                     and parameters
                   (even named ones)

                                       64
Command chains




       %move%left%%at%3.km/h%




                                64
Command chains


       Equivalent to:

       %%%%%(%%%%).%%(%%%%%%)
       %move%left%%at%3.km/h%




                                64
Look  Ma!
No  par ens,
 no dots!
Command chains
          //%Java%fluent%API%approach
          class%Robot%{
          %%%%...
          $$$$def%move(Direction%dir)%{
          %%%%%%%%this.dir%=%dir
          %%%%%%%%return%this
          %%%%}

          %%%%def%at(Speed%speed)%{
          %%%%%%%%this.speed%=%speed
          %%%%%%%%return%this
          %%%%}
          %%%%...
          }
                                          66
Command chains
   def)move(Direction)dir)){
   ))))[at:){)Speed)speed)F>
   ))))))))))))...
   ))))))))}]
   ))))}]
   }




                               67
Command chains
   def)move(Direction)dir)){
   ))))[at:){)Speed)speed)F>
   ))))))))))))...             Nested maps
   ))))))))}]                  and closures
   ))))}]
   }




                                              67
Command chains
   def)move(Direction)dir)){
   ))))[at:){)Speed)speed)F>
   ))))))))))))...                 Nested maps
   ))))))))}]                      and closures
   ))))}]
   }

            Usage in
           your DSLs   move%left%at%3.km/h

                                                  67
Command chains




                 68
Command chains
   //%methods%with%multiple%arguments%(commas)




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




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

   //%leverage%namedfargs%as%punctuation




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

   //%closure%parameters%for%new%control%structures




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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

   //%zerofarg%methods%require%parens




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names




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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names

   //%possible%with%an%odd%number%of%terms

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

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
                                                      68
Command chains
   //%methods%with%multiple%arguments%(commas)
   take%coffee%%with%sugar,%milk%%and%liquor
   %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%)

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
                                                      68
Command chains
   //%methods%with%multiple%arguments%(commas)
   take%coffee%%with%sugar,%milk%%and%liquor
   %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%)

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good
   %%%%%(%%%%%%%%%%%).%%%%%%(%%%%)

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
                                                      68
Command chains
   //%methods%with%multiple%arguments%(commas)
   take%coffee%%with%sugar,%milk%%and%liquor
   %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%)

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good
   %%%%%(%%%%%%%%%%%).%%%%%%(%%%%)

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
                                                      68
Command chains
   //%methods%with%multiple%arguments%(commas)
   take%coffee%%with%sugar,%milk%%and%liquor
   %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%)

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good
   %%%%%(%%%%%%%%%%%).%%%%%%(%%%%)

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names
   %%%%%%(%%%).%%%%%%%%.%%%%(%%%%%)

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
                                                      68
Command chains
   //%methods%with%multiple%arguments%(commas)
   take%coffee%%with%sugar,%milk%%and%liquor
   %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%)

   //%leverage%namedfargs%as%punctuation
   check%that:%vodka%%tastes%good
   %%%%%(%%%%%%%%%%%).%%%%%%(%%%%)

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

   //%zerofarg%methods%require%parens
   select%all%%unique()%from%names
   %%%%%%(%%%).%%%%%%%%.%%%%(%%%%%)

   //%possible%with%an%odd%number%of%terms
   deploy%left%%arm
   %%%%%%(%%%%).
                                                      68
Final result




               69
Final result



          move!forward!at!3.km/h




                                   69
move forward
 at 3.km/h
move forward
 at 3.km/h     Yes! We did it!
What about security
   and safety?
Security and safety
     JVM Security Managers
     SecureASTCustomizer
            Sandboxing
   Controlling scripts execution




                                   72
Play it safe in a sandbox
Playing it safe...

•   You have to think carefully about
    what DSL users are allowed to do with your DSL


•   Forbid things which are not allowed
    •leverage the JVM’s Security Managers
        •
       this might have an impact on performance
    •use a Secure AST compilation customizer
        •
       not so easy to think about all possible cases
    •avoid long running scripts with *Interrupt transformations



                                                                  74
Security Managers

•   Groovy is just a language leaving on the JVM,
    so you have access to the usual Security Managers mechanism
    • Nothing Groovy specific here
    • Please check the documentation on Security Managers
      and how to design policy files




                                                                  75
SecureASTCustomizer
      def!secure!=!new!SecureASTCustomizer()
      secure.with!{
         //!disallow!closure!creation
      !!!closuresAllowed!=!false!
         //!disallow!method!definitions
      !!!methodDefinitionAllowed!=!false!
         //!empty!white!list!=>!forbid!certain!imports
      !!!importsWhitelist!=![...]!
      !!!staticImportsWhitelist!=![...]
         //!only!allow!some!static!import
      !!!staticStarImportsWhitelist!=![...]
         //!language!tokens!allowed
      !!!!tokensWhitelist!=![...]
         //!types!allowed!to!be!used
      !!!constantTypesClassesWhiteList!=![...]
         //!classes!who!are!allowed!to!be!receivers!of!method!calls
      !!!receiversClassesWhiteList!=![...]
      }
      def!config!=!new!CompilerConfiguration()
      config.addCompilationCustomizers(secure)
      def!shell!=!new!GroovyShell(config)
                                                                      76
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
                                                                  77
@ThreadInterrupt

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


  %%%%//%Any%extraterestrial%around?
  }



                                             78
@ThreadInterrupt

    @ThreadInterrupt
    import%groovy.transform.ThreadInterrupt%
    %
    while%(true)%{
{   %%%%if%(Thread.currentThread.isInterrupted())
    %%%%%%%%throw$new%InterruptedException()
                                                    }
    %%%%//%Any%extraterestrial%around?
    }



                                                        78
@TimedInterrupt
                @TimedInterrupt(10)
                import!groovy.transform.TimedInterrupt!
                !
                while!(true)!{
                !!!!move!left
                !!!!//!circle!forever
                }


•   InterruptedException thrown
    when checks indicate code ran longer than desired



                                                          79
@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({$battery.level$<$O.1$})
                  import%groovy.transform.ConditionalInterrupt

                  100.times%{%%%%
                  %%%%move%forward%at%10.km/h
                  }


                                                                    80
Using compilation customizers

•   In our previous three examples, the usage of the interrupts were explicit,
    and users had to type them
    • if they want to deplete the battery of your robot,
      they won’t use interrupts, so you have to impose interrupts yourself


•   With compilation customizers you can inject those interrupts
    thanks to the ASTTransformationCustomizer




                                                                                 81
What have we learnt?




                       82
Groovy Power!™

•   A flexible and malleable syntax
    • scripts vs classes, optional typing, colons and parens
•   Groovy offers useful dynamic features for DSLs
    • operator overloading, ExpandoMetaClass
•   Can write almost plain natural language sentences
    • for readable, concise and expressive DSLs
•   Groovy DSLs are easy to integrate,
    and can be secured to run safely in your own sandbox



                                                               83
Groovy Power!™                         Groovy is a
                                       great fit for
                                          DSLs!

•   A flexible and malleable syntax
    • scripts vs classes, optional typing, colons and parens
•   Groovy offers useful dynamic features for DSLs
    • operator overloading, ExpandoMetaClass
•   Can write almost plain natural language sentences
    • for readable, concise and expressive DSLs
•   Groovy DSLs are easy to integrate,
    and can be secured to run safely in your own sandbox



                                                               83
And there’s more!

•   We haven’t dived into...
    •How to implement your own control structures with the help of closures
    •How to create Groovy « builders »
    •How to hijack the Groovy syntax to develop our own language extensions with
     AST Transformations
    •Source preprocessing for custom syntax
    •How to use the other dynamic metaprogramming techniques available
    •How to improve error reporting with customizers
    •IDE support with DSL descriptors (GDSL and DSLD)


                                                                                   84
Thank you!



                                   ge
                          e   Lafor lopment
             Gui llaum ovy Deve
             Head   of Gro
                                          om
                               @  gmail.c
                       laforge rge
              Email: g @glafo             o/glaforg
                                                   e
              Twitter : http://gplus.t spot.com
                           :
               G oogle+ //glaforge.app
                           p:
               B  log: htt




                                                       85
Questions & Answers


Got questions,
    really?




                      86
Questions & Answers

                      I might have
                        answers!
Got questions,
    really?




                                     86
Image credits
•   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
•   Russian flag: http://good-wallpapers.com/pictures/4794/Russian%20Flag.jpg
•   Space odissey: http://dearjesus.files.wordpress.com/2010/04/2001_a_space_odyssey_1.jpg
•   HAL red: http://2.bp.blogspot.com/-yjsyPxUFicY/TcazwAltOaI/AAAAAAAAAho/GVT7wGhnrUM/s1600/2001-a-space-odyssey-HAL.jpg
•   Back in time: http://4.bp.blogspot.com/-Pt44Dk9J2EM/TrQx9YNmVcI/AAAAAAAAAk4/ivWw9Lja05k/s1600/clocky.jpg
•   USSR Space posters: http://www.flickr.com/photos/justinvg
•   Russian General: http://rickrozoff.files.wordpress.com/2012/02/general-nikolai-makarov.jpg
•   Rocket: http://blog.al.com/breaking/2009/03/soyuz_launch.jpg
•   Progress capsule: http://www.spacedaily.com/images/progress-ocean-desk-1024.jpg
•   Buran: http://www.buran.fr/mriya-antonov/Photos//050-Exhibition%20au%20Bourget%20avec%20Bourane-Airshow%20with%20Buran%20at%20Le%20Bourget-1134884.jpg
•   Man in space: http://vintagespace.files.wordpress.com/2010/11/voskhod-2_leonov.jpg
•   Sputnik 2: http://launiusr.files.wordpress.com/2010/06/sputnik2.jpg
•   Lunakod: http://www.astr.ua.edu/keel/space/lunakhod_moscow.jpg
•   Sandbox: http://www.turnbacktogod.com/wp-content/uploads/2008/09/sandbox.jpg
•   Repair: http://www.oneangels.com/wp-content/uploads/2012/03/repair1.jpg
•   Mars rover: http://wallpapers.free-review.net/wallpapers/49/Mars_rover%2C_Mars_-_03.jpg
•   Mars rover 2: http://www.universetoday.com/wp-content/uploads/2011/06/551038main_pia14156-43_946-710.jpg
•   Thumb: http://www.wpclipart.com/sign_language/thumbs_up_large.png.html
•   Night sky: http://www.aplf-planetariums.info/galeries/ciel_profond/2004-07-01-Voie_Lactee_Scorpion-Jean-Luc_PUGLIESI.jpg
•   Obama yes we can: http://www.dessinemoiunboulon.net/wp-content/uploads/2009/01/obama-yes-we-can_04-nov-08.jpg
•   Hook: http://winningware.com/blog/wp-content/uploads/2009/12/FishHookXSmall.jpg
•   HP 48 GX: http://calculators.torensma.net/files/images/hewlett-packard_hp-48g.jpg
•   Omer: http://www.irmin.com/wallpaper/TV/Homer%20Simpson%20Oh%20No.jpg
•   Cadenat: http://acsgsecurite.com/upl/site/cadenat.png




                                                                                                                                                             87

More Related Content

What's hot

Understanding OpenID
Understanding OpenIDUnderstanding OpenID
Understanding OpenID
Prabath Siriwardena
 
REST - Representational State Transfer
REST - Representational State TransferREST - Representational State Transfer
REST - Representational State Transfer
Peter R. Egli
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
Antoine Rey
 
Mvc architecture
Mvc architectureMvc architecture
Mvc architecture
Surbhi Panhalkar
 
Getting Started with Spring Authorization Server
Getting Started with Spring Authorization ServerGetting Started with Spring Authorization Server
Getting Started with Spring Authorization Server
VMware Tanzu
 
The evolution of Apache Calcite and its Community
The evolution of Apache Calcite and its CommunityThe evolution of Apache Calcite and its Community
The evolution of Apache Calcite and its Community
Julian Hyde
 
OpenID for Verifiable Credentials
OpenID for Verifiable CredentialsOpenID for Verifiable Credentials
OpenID for Verifiable Credentials
Torsten Lodderstedt
 
REST API Design & Development
REST API Design & DevelopmentREST API Design & Development
REST API Design & Development
Ashok Pundit
 
Simple object access protocol(soap )
Simple object access protocol(soap )Simple object access protocol(soap )
Simple object access protocol(soap )
balamurugan.k Kalibalamurugan
 
ORM: Object-relational mapping
ORM: Object-relational mappingORM: Object-relational mapping
ORM: Object-relational mapping
Abhilash M A
 
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in ProductionKong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
FIWARE
 
Apache Calcite overview
Apache Calcite overviewApache Calcite overview
Apache Calcite overview
Julian Hyde
 
Introduction to EJB
Introduction to EJBIntroduction to EJB
Introduction to EJB
Return on Intelligence
 
Introduction to SAML 2.0
Introduction to SAML 2.0Introduction to SAML 2.0
Introduction to SAML 2.0
Mika Koivisto
 
OpenID Connect for W3C Verifiable Credential Objects
OpenID Connect for W3C Verifiable Credential ObjectsOpenID Connect for W3C Verifiable Credential Objects
OpenID Connect for W3C Verifiable Credential Objects
Torsten Lodderstedt
 
FIWARE Training: IoT and Legacy
FIWARE Training: IoT and LegacyFIWARE Training: IoT and Legacy
FIWARE Training: IoT and Legacy
FIWARE
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
Jesus Perez Franco
 
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Julian Hyde
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By Step
Guo Albert
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
Arun Gupta
 

What's hot (20)

Understanding OpenID
Understanding OpenIDUnderstanding OpenID
Understanding OpenID
 
REST - Representational State Transfer
REST - Representational State TransferREST - Representational State Transfer
REST - Representational State Transfer
 
Spring Framework Petclinic sample application
Spring Framework Petclinic sample applicationSpring Framework Petclinic sample application
Spring Framework Petclinic sample application
 
Mvc architecture
Mvc architectureMvc architecture
Mvc architecture
 
Getting Started with Spring Authorization Server
Getting Started with Spring Authorization ServerGetting Started with Spring Authorization Server
Getting Started with Spring Authorization Server
 
The evolution of Apache Calcite and its Community
The evolution of Apache Calcite and its CommunityThe evolution of Apache Calcite and its Community
The evolution of Apache Calcite and its Community
 
OpenID for Verifiable Credentials
OpenID for Verifiable CredentialsOpenID for Verifiable Credentials
OpenID for Verifiable Credentials
 
REST API Design & Development
REST API Design & DevelopmentREST API Design & Development
REST API Design & Development
 
Simple object access protocol(soap )
Simple object access protocol(soap )Simple object access protocol(soap )
Simple object access protocol(soap )
 
ORM: Object-relational mapping
ORM: Object-relational mappingORM: Object-relational mapping
ORM: Object-relational mapping
 
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in ProductionKong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
Kong, Keyrock, Keycloak, i4Trust - Options to Secure FIWARE in Production
 
Apache Calcite overview
Apache Calcite overviewApache Calcite overview
Apache Calcite overview
 
Introduction to EJB
Introduction to EJBIntroduction to EJB
Introduction to EJB
 
Introduction to SAML 2.0
Introduction to SAML 2.0Introduction to SAML 2.0
Introduction to SAML 2.0
 
OpenID Connect for W3C Verifiable Credential Objects
OpenID Connect for W3C Verifiable Credential ObjectsOpenID Connect for W3C Verifiable Credential Objects
OpenID Connect for W3C Verifiable Credential Objects
 
FIWARE Training: IoT and Legacy
FIWARE Training: IoT and LegacyFIWARE Training: IoT and Legacy
FIWARE Training: IoT and Legacy
 
Spring Security 5
Spring Security 5Spring Security 5
Spring Security 5
 
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
Apache Calcite: A Foundational Framework for Optimized Query Processing Over ...
 
Java Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By StepJava Persistence API (JPA) Step By Step
Java Persistence API (JPA) Step By Step
 
JAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web ServicesJAX-RS 2.0: RESTful Web Services
JAX-RS 2.0: RESTful Web Services
 

Viewers also liked

4. heredity and evolution
4. heredity and evolution4. heredity and evolution
4. heredity and evolution
Abhay Goyal
 
5000 Sat Words With Definitions
5000 Sat Words With Definitions5000 Sat Words With Definitions
5000 Sat Words With Definitions
Brent Daigle, Ph.D.
 
Engaging Learners with Technology
Engaging Learners with TechnologyEngaging Learners with Technology
Engaging Learners with Technology
Dean Shareski
 
Simple Steps to UX/UI Web Design
Simple Steps to UX/UI Web DesignSimple Steps to UX/UI Web Design
Simple Steps to UX/UI Web Design
Koombea
 
Lean Manufacturing - Toyota Production System
Lean Manufacturing - Toyota Production SystemLean Manufacturing - Toyota Production System
Lean Manufacturing - Toyota Production System
Mohammed Hamed Ahmed Soliman
 
Becoming a Design Leader
Becoming a Design LeaderBecoming a Design Leader
Becoming a Design Leader
frog
 
File three 4 am great expectations- with atf anf aef competencies
File three 4 am  great expectations- with atf anf aef competenciesFile three 4 am  great expectations- with atf anf aef competencies
File three 4 am great expectations- with atf anf aef competencies
Mr Bounab Samir
 
Mathematics high school level quiz - Part I
Mathematics high school level quiz - Part IMathematics high school level quiz - Part I
Mathematics high school level quiz - Part I
ITfC-Edu-Team
 
PowerPoint Hacks for Rookies: 4 Must Consider Aspects
PowerPoint Hacks for Rookies: 4 Must Consider AspectsPowerPoint Hacks for Rookies: 4 Must Consider Aspects
PowerPoint Hacks for Rookies: 4 Must Consider Aspects
24Slides
 
Mri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin ZulfiqarMri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin Zulfiqar
Dr. Muhammad Bin Zulfiqar
 
The Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing ContentThe Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing Content
Neil Patel
 
How to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksHow to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & Tricks
SlideShare
 
What I Carry: 10 Tools for Success
What I Carry: 10 Tools for SuccessWhat I Carry: 10 Tools for Success
What I Carry: 10 Tools for Success
Jonathon Colman
 
Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017
Techsauce Media
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
Oneupweb
 
Dear NSA, let me take care of your slides.
Dear NSA, let me take care of your slides.Dear NSA, let me take care of your slides.
Dear NSA, let me take care of your slides.
Emiland
 
61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook
Consonaute
 
Tweak Your Resume
Tweak Your ResumeTweak Your Resume
Tweak Your Resume
Chiara Ojeda
 
BUSINESS QUIZ -Round 1
 BUSINESS QUIZ -Round 1 BUSINESS QUIZ -Round 1
BUSINESS QUIZ -Round 1
pradeep acharya
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShare
SlideShare
 

Viewers also liked (20)

4. heredity and evolution
4. heredity and evolution4. heredity and evolution
4. heredity and evolution
 
5000 Sat Words With Definitions
5000 Sat Words With Definitions5000 Sat Words With Definitions
5000 Sat Words With Definitions
 
Engaging Learners with Technology
Engaging Learners with TechnologyEngaging Learners with Technology
Engaging Learners with Technology
 
Simple Steps to UX/UI Web Design
Simple Steps to UX/UI Web DesignSimple Steps to UX/UI Web Design
Simple Steps to UX/UI Web Design
 
Lean Manufacturing - Toyota Production System
Lean Manufacturing - Toyota Production SystemLean Manufacturing - Toyota Production System
Lean Manufacturing - Toyota Production System
 
Becoming a Design Leader
Becoming a Design LeaderBecoming a Design Leader
Becoming a Design Leader
 
File three 4 am great expectations- with atf anf aef competencies
File three 4 am  great expectations- with atf anf aef competenciesFile three 4 am  great expectations- with atf anf aef competencies
File three 4 am great expectations- with atf anf aef competencies
 
Mathematics high school level quiz - Part I
Mathematics high school level quiz - Part IMathematics high school level quiz - Part I
Mathematics high school level quiz - Part I
 
PowerPoint Hacks for Rookies: 4 Must Consider Aspects
PowerPoint Hacks for Rookies: 4 Must Consider AspectsPowerPoint Hacks for Rookies: 4 Must Consider Aspects
PowerPoint Hacks for Rookies: 4 Must Consider Aspects
 
Mri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin ZulfiqarMri brain anatomy Dr Muhammad Bin Zulfiqar
Mri brain anatomy Dr Muhammad Bin Zulfiqar
 
The Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing ContentThe Ultimate Guide to Creating Visually Appealing Content
The Ultimate Guide to Creating Visually Appealing Content
 
How to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & TricksHow to Make Awesome SlideShares: Tips & Tricks
How to Make Awesome SlideShares: Tips & Tricks
 
What I Carry: 10 Tools for Success
What I Carry: 10 Tools for SuccessWhat I Carry: 10 Tools for Success
What I Carry: 10 Tools for Success
 
Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017Thai tech startup ecosystem report 2017
Thai tech startup ecosystem report 2017
 
10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization10 Ways to Win at SlideShare SEO & Presentation Optimization
10 Ways to Win at SlideShare SEO & Presentation Optimization
 
Dear NSA, let me take care of your slides.
Dear NSA, let me take care of your slides.Dear NSA, let me take care of your slides.
Dear NSA, let me take care of your slides.
 
61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook61 Beautiful & Inspirational Timeline Cover on Facebook
61 Beautiful & Inspirational Timeline Cover on Facebook
 
Tweak Your Resume
Tweak Your ResumeTweak Your Resume
Tweak Your Resume
 
BUSINESS QUIZ -Round 1
 BUSINESS QUIZ -Round 1 BUSINESS QUIZ -Round 1
BUSINESS QUIZ -Round 1
 
What to Upload to SlideShare
What to Upload to SlideShareWhat to Upload to SlideShare
What to Upload to SlideShare
 

Similar to Going to Mars with Groovy Domain-Specific Languages

Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
Guillaume Laforge
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Guillaume Laforge
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
GWTcon
 
Java - A broad introduction
Java - A broad introductionJava - A broad introduction
Java - A broad introduction
Birol Efe
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
Guillaume Laforge
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Guillaume Laforge
 
Schema registries and Snowplow
Schema registries and SnowplowSchema registries and Snowplow
Schema registries and Snowplow
miiker
 
Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009
spierre
 
Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)
Robert Lemke
 
Philip Stehlik at TechTalks.ph - Intro to Groovy and Grails
Philip Stehlik at TechTalks.ph - Intro to Groovy and GrailsPhilip Stehlik at TechTalks.ph - Intro to Groovy and Grails
Philip Stehlik at TechTalks.ph - Intro to Groovy and Grails
Philip Stehlik
 
Andriy Shalaenko - GO security tips
Andriy Shalaenko - GO security tipsAndriy Shalaenko - GO security tips
Andriy Shalaenko - GO security tips
OWASP Kyiv
 
IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3
Robert Lemke
 
MozillaPH Rust Hack & Learn Session 1
MozillaPH Rust Hack & Learn Session 1MozillaPH Rust Hack & Learn Session 1
MozillaPH Rust Hack & Learn Session 1
Robert 'Bob' Reyes
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化
Tomoharu ASAMI
 
Tml for Objective C
Tml for Objective CTml for Objective C
Tml for Objective C
Michael Berkovich
 
Polyglot Applications with GraalVM
Polyglot Applications with GraalVMPolyglot Applications with GraalVM
Polyglot Applications with GraalVM
jexp
 
Linked Process
Linked ProcessLinked Process
Linked Process
Joshua Shinavier
 
Introduction to JavaScript
Introduction to JavaScriptIntroduction to JavaScript
Introduction to JavaScript
Jussi Pohjolainen
 
Drools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentationDrools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentation
Mark Proctor
 
Tips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software EngineeringTips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software Engineering
jtdudley
 

Similar to Going to Mars with Groovy Domain-Specific Languages (20)

Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
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...
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
Java - A broad introduction
Java - A broad introductionJava - A broad introduction
Java - A broad introduction
 
Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007Groovy Update - JavaPolis 2007
Groovy Update - JavaPolis 2007
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
 
Schema registries and Snowplow
Schema registries and SnowplowSchema registries and Snowplow
Schema registries and Snowplow
 
Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009Sugar Presentation - YULHackers March 2009
Sugar Presentation - YULHackers March 2009
 
Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)Getting Into FLOW3 (DPC12)
Getting Into FLOW3 (DPC12)
 
Philip Stehlik at TechTalks.ph - Intro to Groovy and Grails
Philip Stehlik at TechTalks.ph - Intro to Groovy and GrailsPhilip Stehlik at TechTalks.ph - Intro to Groovy and Grails
Philip Stehlik at TechTalks.ph - Intro to Groovy and Grails
 
Andriy Shalaenko - GO security tips
Andriy Shalaenko - GO security tipsAndriy Shalaenko - GO security tips
Andriy Shalaenko - GO security tips
 
IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3IPCSE12: Getting into FLOW3
IPCSE12: Getting into FLOW3
 
MozillaPH Rust Hack & Learn Session 1
MozillaPH Rust Hack & Learn Session 1MozillaPH Rust Hack & Learn Session 1
MozillaPH Rust Hack & Learn Session 1
 
DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化DIとトレイとによるAndroid開発の効率化
DIとトレイとによるAndroid開発の効率化
 
Tml for Objective C
Tml for Objective CTml for Objective C
Tml for Objective C
 
Polyglot Applications with GraalVM
Polyglot Applications with GraalVMPolyglot Applications with GraalVM
Polyglot Applications with GraalVM
 
Linked Process
Linked ProcessLinked Process
Linked Process
 
Introduction to JavaScript
Introduction to JavaScriptIntroduction to JavaScript
Introduction to JavaScript
 
Drools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentationDrools, jBPM OptaPlanner presentation
Drools, jBPM OptaPlanner presentation
 
Tips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software EngineeringTips And Tricks For Bioinformatics Software Engineering
Tips And Tricks For Bioinformatics Software Engineering
 

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 2013
Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
Guillaume 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 2013
Guillaume Laforge
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
Guillaume 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 2012
Guillaume Laforge
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
Guillaume Laforge
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
Guillaume Laforge
 
JavaOne 2012 Groovy update
JavaOne 2012 Groovy updateJavaOne 2012 Groovy update
JavaOne 2012 Groovy update
Guillaume Laforge
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Guillaume Laforge
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Guillaume 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 Laforge
Guillaume Laforge
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
Guillaume Laforge
 
Whats new in Groovy 2.0?
Whats new in Groovy 2.0?Whats new in Groovy 2.0?
Whats new in Groovy 2.0?
Guillaume Laforge
 
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Guillaume Laforge
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGuillaume Laforge
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011
Guillaume Laforge
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Guillaume Laforge
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Guillaume Laforge
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovyGuillaume Laforge
 
Groovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume LaforgeGroovy update - S2GForum London 2011 - Guillaume Laforge
Groovy update - S2GForum London 2011 - Guillaume Laforge
Guillaume 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 update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
 
JavaOne 2012 Groovy update
JavaOne 2012 Groovy updateJavaOne 2012 Groovy update
JavaOne 2012 Groovy update
 
Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012Groovy 1.8 et 2.0 au BreizhC@mp 2012
Groovy 1.8 et 2.0 au BreizhC@mp 2012
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 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
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
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, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
Groovy Update, new in 1.8 and beyond - Guillaume Laforge - Devoxx 2011
 
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume LaforgeGPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
GPars et PrettyTime - Paris JUG 2011 - Guillaume Laforge
 
Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011Groovy Update - Guillaume Laforge - Greach 2011
Groovy Update - Guillaume Laforge - Greach 2011
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
 
Cloud foundry intro with groovy
Cloud foundry intro with groovyCloud foundry intro with groovy
Cloud foundry intro with groovy
 
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
 

Recently uploaded

Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
Zilliz
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
Neo4j
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Paige Cruz
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
SOFTTECHHUB
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Malak Abu Hammad
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
mikeeftimakis1
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
Rohit Gautam
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Speck&Tech
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
DianaGray10
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
Matthew Sinclair
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems S.M.S.A.
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 

Recently uploaded (20)

Full-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalizationFull-RAG: A modern architecture for hyper-personalization
Full-RAG: A modern architecture for hyper-personalization
 
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
GraphSummit Singapore | Neo4j Product Vision & Roadmap - Q2 2024
 
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdfObservability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
Observability Concepts EVERY Developer Should Know -- DeveloperWeek Europe.pdf
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
Why You Should Replace Windows 11 with Nitrux Linux 3.5.0 for enhanced perfor...
 
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdfUnlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
Unlock the Future of Search with MongoDB Atlas_ Vector Search Unleashed.pdf
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
Introduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - CybersecurityIntroduction to CHERI technology - Cybersecurity
Introduction to CHERI technology - Cybersecurity
 
Large Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial ApplicationsLarge Language Model (LLM) and it’s Geospatial Applications
Large Language Model (LLM) and it’s Geospatial Applications
 
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
Cosa hanno in comune un mattoncino Lego e la backdoor XZ?
 
UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5UiPath Test Automation using UiPath Test Suite series, part 5
UiPath Test Automation using UiPath Test Suite series, part 5
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
20240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 202420240609 QFM020 Irresponsible AI Reading List May 2024
20240609 QFM020 Irresponsible AI Reading List May 2024
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Uni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdfUni Systems Copilot event_05062024_C.Vlachos.pdf
Uni Systems Copilot event_05062024_C.Vlachos.pdf
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 

Going to Mars with Groovy Domain-Specific Languages

  • 1. Groovy Domain Specific Guillaume Laforge Groovy Project Manager SpringSource / VMware Languages @glaforge 1
  • 3. Guillaume Laforge • Groovy Project Manager at VMware •Initiator of the Grails framework •Creator of the Gaelyk and Caelyf toolkits • Co-author of Groovy in Action • Follow me on... •My blog: http://glaforge.appspot.com •Twitter: @glaforge •Google+: http://gplus.to/glaforge 3
  • 5. Domain-Specific Languages • Wikipedia definition { } A Domain-Specific Language is a programming language or executable specification language that offers, through appropriate notations and abstractions, expressive power focused on, and usually restricted to, a particular problem domain. • In contrast to General Purprose Languages • Also known as: fluent / human interfaces, language oriented programming, little or mini languages, macros, business natural languages... 5
  • 6. Technical examples Glade XSLT <?xml version="1.0"?> <?xml version="1.0"?> <GTK-Interface> <xsl:stylesheetversion="1.0" <widget> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <class>GtkWindow</class> <xsl:output method="xml"/> <name>HelloWindow</name> <xsl:template match="*"> <border_width>5</border_width> <Signal> <xsl:element name="{name()}"> Regex <xsl:for-each select="@*"> <name>destroy</name> <handler>gtk_main_quit</handler> <xsl:element name="{name()}"> <xsl:value-of select="."/> "x.z?z{1,3}y" </Signal> <title>Hello</title> </xsl:element> <type>GTK_WINDOW_TOPLEVEL</type> </xsl:for-each> <position>GTK_WIN_POS_NONE</position> <xsl:apply-templates select="*|text()"/> <allow_shrink>True</allow_shrink> </xsl:element> <allow_grow>True</allow_grow> </xsl:template> <auto_shrink>False</auto_shrink> </xsl:stylesheet> <widget> <class>GtkButton</class> <name>Hello World</name> <can_focus>True</can_focus> fetchmail <label>Hello World</label> # Poll this site first each cycle. </widget> poll pop.provider.net proto pop3 </widget> user "jsmith" with pass "secret1" is "smith" here </GTK-Interface> user jones with pass "secret2" is "jjones" here with options keep SQL # Poll this site second, unless Lord Voldemort zaps us first. poll billywig.hogwarts.com with proto imap: user harry_potter with pass "floo" is harry_potter here SELECT * FROM TABLE # Poll this site third in the cycle. WHERE NAME LIKE '%SMI' # Password will be fetched from ~/.netrc ORDER BY NAME poll mailhost.net with proto imap: user esr is esr here
  • 7. Antimalaria drug Insurance policy risk HR skills representation resistance simulation calculation engine Nuclear safety simulations Market data feeds analysis Loan acceptance rules engine
  • 8. Goals of DSLs • Use a more expressive language than a general-purpose one • Share a common metaphor of understanding between developers and subject matter experts • Have domain experts help with the design of the business logic of an application • Avoid cluttering business code with too much boilerplate technical code thanks to a clean separation • Let business rules have their own lifecycle 8
  • 9. Pros and cons Pros Cons • Domain experts can help, validate, • Learning cost vs. limited applicability modify, and often develop DSL programs • Cost of designing, implementing & maintaining DSLs as well as tools/IDEs • Somewhat self-documenting • Attaining proper scope • Enhance quality, productivity, • Trade-offs between domain specificity reliability, maintainability, portability, and general purpose language reusability constructs • Safety; as long as the language • Efficiency cost constructs are safe, any DSL sentence can be considered safe • Proliferation of similar non-standard DSLs 9
  • 10. Groovy provides... • A flexible and malleable syntax •scripts, native syntax constructs (list, map, ranges), closures, less punctuation... • Compile-time and runtime meta-programming •metaclasses, AST transformations •also operator overloading • The ability to easily integrate into Java / Spring apps •also security and safety 10
  • 12.
  • 13. Your mission: build a DSL for a Mars robot
  • 14. We need a robot! class!Robot!{} 14
  • 15. It should move... class!Robot!{ !!!!void)move()!{} } 15
  • 16. ..in a direction! class!Robot!{ !!!!void)move(String!dir)!{} } 16
  • 17. More explicit direction class!Robot!{ !!!!void)move(Direction!dir)!{} } enum!Direction!{ !!!!left,!right,!forward,!backward } 17
  • 18. Now how can we control it? import)static)mars.Direction.*; import)mars.Robot; public)class)Command!{ ))))public)static)void)main(String[]!args)!{ !!!!!!!!Robot!robot!=)new!Robot(); !!!!!!!!robot.move(left); !!!!} } 18
  • 19. Now how can we control it? import)static)mars.Direction.*; import)mars.Robot; public)class)Command!{ ))))public)static)void)main(String[]!args)!{ !!!!!!!!Robot!robot!=)new!Robot(); !!!!!!!!robot.move(left); !!!!} } Syntactical noise! 18
  • 20. Now how can we control it? ))))))))))))))))))))))))))))))— import)static)mars.Direction.*; )))))))))))))))))— import)mars.Robot; —————————————————————— public)class)Command!{ ))))———————————————————————————————————————— ))))public)static)void)main(String[]!args)!{ ))))))))—————))))))))))))))))))))— !!!!!!!!Robot!robot!=)new!Robot(); ))))))))))))))))))—))))—— !!!!!!!!robot.move(left); ))))— !!!!} — } Syntactical noise! 18
  • 21. Scripts vs Classes Optional semicolons & parens import)static)mars.Direction.* import)mars.Robot !!!!!!!!def))!robot!=)new!Robot() !!!!!!!!robot.move!left 19
  • 22. Scripts vs Classes Optional semicolons & parens import)static)mars.Direction.* import)mars.Robot Optional typing !!!!!!!!def))!robot!=)new!Robot() !!!!!!!!robot.move!left 19
  • 23. Scripts vs Classes Optional semicolons & parens import)static)mars.Direction.* import)mars.Robot Optional typing !!!!!!!!def))!robot!=)new!Robot() !!!!!!!!robot.move!left But I don’t want to compile a script for every command! 19
  • 25. GroovyShell to the rescue 21
  • 26. GroovyShell to the rescue def$shell%=$new%GroovyShell() shell.evaluate( %%%%new%File("command.groovy") ) 21
  • 27. GroovyShell to the rescue def$shell%=$new%GroovyShell() shell.evaluate( integration.groovy %%%%new%File("command.groovy") ) 21
  • 28. GroovyShell to the rescue def$shell%=$new%GroovyShell() shell.evaluate( integration.groovy %%%%new%File("command.groovy") ) import$static$mars.Direction.* import$mars.Robot def$robot%=$new%Robot() robot.move%left 21
  • 29. GroovyShell to the rescue def$shell%=$new%GroovyShell() shell.evaluate( integration.groovy %%%%new%File("command.groovy") ) import$static$mars.Direction.* import$mars.Robot command.groovy def$robot%=$new%Robot() robot.move%left 21
  • 30. Integration mechanisms • Different solutions available: •Groovy’s own mechanisms • GroovyScriptEngine, Eval, GroovyClassLoader, GroovyShell •Java 6: javax.script.* / JSR-223 • Groovy provides a JSR-223 implementation •Spring’s lang namespace • Groovy provides the highest level of flexibility and customization, but JSR-223 is a standard... 22
  • 31. Integration mechanisms • Different solutions available: •Groovy’s own mechanisms • GroovyScriptEngine, Eval, GroovyClassLoader, GroovyShell •Java 6: javax.script.* / JSR-223 • Groovy provides a JSR-223 implementation •Spring’s lang namespace • Groovy provides the highest level of flexibility and customization, but JSR-223 is a standard... 22
  • 32. What’s wrong with our DSL? import)static)mars.Direction.* import)mars.Robot def)robot!=)new!Robot() robot.move!left 23
  • 33. What’s wrong with our DSL? Can’t we hide those imports? import)static)mars.Direction.* import)mars.Robot def)robot!=)new!Robot() robot.move!left 23
  • 34. What’s wrong with our DSL? Can’t we hide those imports? import)static)mars.Direction.* import)mars.Robot def)robot!=)new!Robot() robot.move!left Can’t we inject the robot? 23
  • 35. What’s wrong with our DSL? Can’t we hide those imports? import)static)mars.Direction.* import)mars.Robot def)robot!=)new!Robot() robot.move!left Can’t we inject Do we really need to the robot? repeat ‘robot’? 23
  • 36. I’m sorry Dave, you can’t do that!
  • 37. I’m sorry Dave, you can’t do that!
  • 38. What we really want is... !move!left! 25
  • 39. Let’s inject a robot! • We can pass data in / out of scripts through the Binding •it’s basically just like a map of variable name keys and their associated values 26
  • 40. Let’s inject a robot! • We can pass data in / out of scripts through the Binding •it’s basically just like a map of variable name keys and their associated values def)binding!=)new!Binding([ !!!!robot:!new!Robot() ]) def)shell!=)new!GroovyShell(binding) shell.evaluate( !!!!new!File("command.groovy") ) 26
  • 41. Let’s inject a robot! • We can pass data in / out of scripts through the Binding •it’s basically just like a map of variable name keys and their associated values integration.groovy def)binding!=)new!Binding([ !!!!robot:!new!Robot() ]) def)shell!=)new!GroovyShell(binding) shell.evaluate( !!!!new!File("command.groovy") ) 26
  • 42. Better? import)static)mars.Direction.* robot.move!left 27
  • 43. Better? Robot import removed import)static)mars.Direction.* robot.move!left 27
  • 44. Better? Robot import removed import)static)mars.Direction.* robot.move!left Robot injected, no ‘new’ needed 27
  • 45. How to inject the direction? • Using the binding... def)binding!=)new!Binding([ !!!!robot:!new!Robot(), !!!!left:!!!!!Direction.left, !!!!right:!!!!Direction.right, !!!!backward:!Direction.backward, !!!!forward:!!Direction.forward ]) def)shell!=)new!GroovyShell(binding) shell.evaluate( !!!!new!File("command.groovy") ) 28
  • 46. How to inject the direction? Fragile in case of new directions! • Using the binding... def)binding!=)new!Binding([ !!!!robot:!new!Robot(), !!!!left:!!!!!Direction.left, !!!!right:!!!!Direction.right, !!!!backward:!Direction.backward, !!!!forward:!!Direction.forward ]) def)shell!=)new!GroovyShell(binding) shell.evaluate( !!!!new!File("command.groovy") ) 28
  • 47. How to inject the direction? • Using the binding... def)binding!=)new!Binding([ !!!!robot:!new!Robot(), !!!!*:!Direction.values() !!!!!!!!!!!!.collectEntries!{ !!!!!!!!!!!!!!!![(it.name()):!it] !!!!!!!!!!!!} ]) def)shell!=)new!GroovyShell(binding) shell.evaluate( !!!!new!File("command.groovy") ) 29
  • 48. How to inject the direction? • Using compiler customizers... • Let’s have a look at them 30
  • 49. Compilation customizers • Ability to apply some customization to the Groovy compilation process • Three available customizers •ImportCustomizer: add transparent imports •ASTTransformationCustomizer: injects an AST transform •SecureASTCustomizer: restrict the groovy language to an allowed subset • But you can implement your own 31
  • 50. Imports customizer new!GroovyShell(new!Binding([robot:!new)Robot()])) !!!!.evaluate("import!static!Direction.*n"!+ !!!!!!!!!!!!!!"robot.move!left") 32
  • 51. Imports customizer Cheat with string concatenation? Bad! new!GroovyShell(new!Binding([robot:!new)Robot()])) !!!!.evaluate("import!static!Direction.*n"!+ !!!!!!!!!!!!!!"robot.move!left") 32
  • 52. Imports customizer new!GroovyShell(new!Binding([robot:!new)Robot()])) !!!!.evaluate("import!static!Direction.*n"!+ !!!!!!!!!!!!!!"robot.move!left") 32
  • 53. Imports customizer def!configuration!=!new!CompilerConfiguration() ! def!imports!=!new!ImportCustomizer() imports.addStaticStar(mars.Direction.name) configuration.addCompilationCustomizers(imports)! ! new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!! ! !!!!!!!!!!!!!!!!configuration) !!!!.evaluate("robot.move!left")!!!!!! 33
  • 54. AST transformation customizer def!configuration!=!new!CompilerConfiguration() ! def!imports!=!new!ImportCustomizer() imports.addStaticStar(mars.Direction.name) configuration.addCompilationCustomizers(imports, !!!!!!!!!!!!!new!ASTTransformationCustomizer(Log)) ! new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!! ! !!!!!!!!!!!!!!!!configuration) !!!!.evaluate("robot.move!left"!+!"n" !!!!!!!!!!!!!!"log.info!‘Robot!moved’")!!!!!!!!!!! 34
  • 55. AST transformation customizer def!configuration!=!new!CompilerConfiguration() ! def!imports!=!new!ImportCustomizer() imports.addStaticStar(mars.Direction.name) configuration.addCompilationCustomizers(imports, !!!!!!!!!!!!!new!ASTTransformationCustomizer(Log)) ! new!GroovyShell(new!Binding([robot:!new)Robot()]),!!!!!!! ! !!!!!!!!!!!!!!!!configuration) !!!!.evaluate("robot.move!left"!+!"n" !!!!!!!!!!!!!!"log.info!‘Robot!moved’")!!!!!!!!!!! @Log injects a logger in scripts and classes 34
  • 57. Secure AST customizer Idea: Secure the rocket’s onboard trajectory calculation system by allowing only math expressions to be evaluated by the calculator • Let’s setup our environment •an import customizer to import java.lang.Math.* •prepare a secure AST customizer def%imports%=%new%ImportCustomizer().addStaticStars('java.lang.Math') def%secure%=%new%SecureASTCustomizer() 36
  • 58. 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'] ... 37
  • 59. Secure AST customizer Disallow closures ... and methods 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'] ... 37
  • 60. Secure AST customizer Disallow closures ... and methods secure.with!{ //!disallow!closure!creation closuresAllowed!=!false! //!disallow!method!definitions Black / white list methodDefinitionAllowed!=!false! imports ! //!empty!white!list!=>!forbid!imports importsWhitelist!=![]! staticImportsWhitelist!=![] //!only!allow!the!java.lang.Math.*!static!import staticStarImportsWhitelist!=!['java.lang.Math'] ... 37
  • 61. 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%] } ... 38
  • 62. Secure AST customizer You can build a subset of the Groovy syntax! ... //%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%] } ... 38
  • 63. Secure AST customizer You can build a subset of the Groovy syntax! ... //%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) Black / white list constantTypesClassesWhiteList%=%[ usage of classes 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%] } ... 38
  • 64. Secure AST customizer • Ready to evaluate our flight equations! 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)' 39
  • 65. Back to our robot... robot.move)left 40
  • 66. Back to our robot... Still need to get rid of the robot prefix! robot.move)left 40
  • 68. Can we remove it? да !
  • 69. How to remove the ‘robot’? • Instead of calling the move() method on the robot instance, we should be able to call the move() method directly from within the script • Two approaches: • Inject a ‘move’ closure in the • Use a base script class with a ‘move’ method delegating to the binding with a method pointer robot 42
  • 70. Inject a closure in the binding def$robot%=%new%Robot() binding%=$new%Binding([ %%%%robot:%robot, %%%%*:%Direction.values() %%%%%%%%%%%%.collectEntries%{ %%%%%%%%%%%%%%%%[(it.name()):%it] %%%%%%%%%%%%}, %%%%move:%robot.&move ]) 43
  • 71. Inject a closure in the binding def$robot%=%new%Robot() binding%=$new%Binding([ %%%%robot:%robot, %%%%*:%Direction.values() %%%%%%%%%%%%.collectEntries%{ %%%%%%%%%%%%%%%%[(it.name()):%it] %%%%%%%%%%%%}, %%%%move:%robot.&move ]) Method pointer (a closure) on robot’s move instance method 43
  • 72. Define a base script class abstract)class!RobotBaseScriptClass!!! !!!!!!!extends!Script!{ !!!!void!move(Direction!dir)!{ !!!!!!!!def)robot!=!this.binding.robot !!!!!!!!robot.move!dir !!!!} } 44
  • 73. Define a base script class abstract)class!RobotBaseScriptClass!!! !!!!!!!extends!Script!{ !!!!void!move(Direction!dir)!{ !!!!!!!!def)robot!=!this.binding.robot !!!!!!!!robot.move!dir !!!!} } The move() method is now at the script level 44
  • 74. Define a base script class abstract)class!RobotBaseScriptClass!!! !!!!!!!extends!Script!{ !!!!void!move(Direction!dir)!{ !!!!!!!!def)robot!=!this.binding.robot !!!!!!!!robot.move!dir !!!!} } The move() method is Access the robot through now at the script level the script’s binding 44
  • 75. Configure the base script class def)conf)=)new)CompilerConfiguration() conf.scriptBaseClass)=)RobotBaseScriptClass 45
  • 76. Configure the base script class def)conf)=)new)CompilerConfiguration() conf.scriptBaseClass)=)RobotBaseScriptClass Scripts evaluated with this configuration will inherit from that class 45
  • 77. Ready for lift off! %%move%left
  • 78. Beep, beep... yes but how do you define the speed? ...beep...
  • 80. What we could do now is... move!left,!at:!3.km/h 49
  • 81. What we could do now is... Mix of named and normal parameters move!left,!at:!3.km/h 49
  • 82. What we could do now is... Mix of named and normal parameters move!left,!at:!3.km/h How to add a km property to numbers? 49
  • 83. Adding properties to numbers • We need to: • define units, distance and speed • have a nice notation for them • that’s where we add properties to numbers! 50
  • 84. Unit enum and Distance class enum$DistanceUnit%{ %%%%centimeter%('cm',%%%%0.01), %%%%meter%%%%%%(%'m',%%%%1),% %%%%kilometer%%('km',%1000)% %%%% %%%%String%abbreviation %%%%double%multiplier %%%% %%%%Unit(String%abbr,%double%mult)%{ %%%%%%%%this.abbreviation%=%abbr %%%%%%%%this.multiplier%=%mult% %%%%} %%%%String%toString()%{%abbreviation%}% } 51
  • 85. Unit enum and Distance class @TupleConstructor% enum$DistanceUnit%{ class%Distance%{ %%%%centimeter%('cm',%%%%0.01), %%%%double%amount% %%%%meter%%%%%%(%'m',%%%%1),% %%%%DistanceUnit%unit %%%%kilometer%%('km',%1000)% %%%% %%%%String%toString()%{% %%%%String%abbreviation %%%%%%%%"$amount%$unit"% %%%%double%multiplier %%%%}% %%%% } %%%%Unit(String%abbr,%double%mult)%{ %%%%%%%%this.abbreviation%=%abbr %%%%%%%%this.multiplier%=%mult% %%%%} %%%%String%toString()%{%abbreviation%}% } 51
  • 86. Different techniques • To add dynamic methods or properties, there are several approaches at your disposal: • ExpandoMetaClass • custom MetaClass • Categories • Let’s have a look at the ExpandoMetaClass 52
  • 87. Using ExpandoMetaClass Number.metaClass.getCm%=%{%f>% %%%%new%Distance(delegate,%Unit.centimeter)% } Number.metaClass.getM%=%{%f>% %%%%new%Distance(delegate,%Unit.meter)% } Number.metaClass.getKm%=%{%f>% %%%%new%Distance(delegate,%Unit.kilometer)% } 53
  • 88. Using ExpandoMetaClass Add that to integration.groovy Number.metaClass.getCm%=%{%f>% %%%%new%Distance(delegate,%Unit.centimeter)% } Number.metaClass.getM%=%{%f>% %%%%new%Distance(delegate,%Unit.meter)% } Number.metaClass.getKm%=%{%f>% %%%%new%Distance(delegate,%Unit.kilometer)% } 53
  • 89. Using ExpandoMetaClass Add that to integration.groovy Number.metaClass.getCm%=%{%f>% %%%%new%Distance(delegate,%Unit.centimeter)% } Number.metaClass.getM%=%{%f>% %%%%new%Distance(delegate,%Unit.meter)% } Number.metaClass.getKm%=%{%f>% %%%%new%Distance(delegate,%Unit.kilometer)% } ‘delegate’ is the current number 53
  • 90. Using ExpandoMetaClass Add that to integration.groovy Usage in your DSLs Number.metaClass.getCm%=%{%f>% %%%%new%Distance(delegate,%Unit.centimeter)% } 40.cm! Number.metaClass.getM%=%{%f>% %%%%new%Distance(delegate,%Unit.meter)% 3.5.m } 4.km Number.metaClass.getKm%=%{%f>% %%%%new%Distance(delegate,%Unit.kilometer)% } ‘delegate’ is the current number 53
  • 91. Distance okay, but speed? • For distance, we just added a property access after the number, but we now need to divide (‘div’) by the time 2.km/h 54
  • 92. Distance okay, but speed? • For distance, we just added a property access after the number, but we now need to divide (‘div’) by the time The div() method on Distance 2.km/h 54
  • 93. Distance okay, but speed? • For distance, we just added a property access after the number, but we now need to divide (‘div’) by the time The div() method on Distance 2.km/h An h duration instance in the binding 54
  • 94. First, let’s look at time enum$TimeUnit%{ %%%%hour%%%%%%('h',%%%3600), %%%%minute%%%%('min',%%%60),% %%%%kilometer%('s',%%%%%%1)% %%%% %%%%String%abbreviation %%%%double%multiplier %%%% %%%%TimeUnit(String%abbr,%double%mult)%{ %%%%%%%%this.abbreviation%=%abbr %%%%%%%%this.multiplier%=%mult% %%%%} %%%%String%toString()%{%abbreviation%}% } 55
  • 95. First, let’s look at time @TupleConstructor% class%Duration%{ enum$TimeUnit%{ %%%%double%amount% %%%%hour%%%%%%('h',%%%3600), %%%%TimeUnit%unit %%%%minute%%%%('min',%%%60),% %%%%kilometer%('s',%%%%%%1)% %%%%String%toString()%{% %%%% %%%%%%%%"$amount%$unit"% %%%%String%abbreviation %%%%}% %%%%double%multiplier } %%%% %%%%TimeUnit(String%abbr,%double%mult)%{ %%%%%%%%this.abbreviation%=%abbr %%%%%%%%this.multiplier%=%mult% %%%%} %%%%String%toString()%{%abbreviation%}% } 55
  • 96. Inject the ‘h’ hour constant in the binding def)binding!=)new!Binding([ !!!!robot:!new!Robot(), !!!!*:!Direction.values() !!!!!!!!!!!!.collectEntries!{ !!!!!!!!!!!!!!!![(it.name()):!it] !!!!!!!!!!!!}, !!!!h:!new!Duration(1,!TimeUnit.hour) ]) 56
  • 97. Now at (light!) speed @TupleConstructor) class)Speed){ ))))Distance)distance ))))Duration)duration ))))String)toString()){) ))))))))"$distance/$duration") ))))}) } 57
  • 98. Operator overloading a%+%b%%//%a.plus(b) a%f%b%%//%a.minus(b) • Currency amounts a%*%b%%//%a.multiply(b) • 15.euros + 10.dollars a%/%b%%//%a.div(b) a%%%b%%//%a.modulo(b) • Distance handling a%**%b%//%a.power(b) • 10.km - 10.m a%|%b%%//%a.or(b) a%&%b%%//%a.and(b) • Workflow, concurrency a%^%b%%//%a.xor(b) • taskA | taskB & taskC a[b]%%%//%a.getAt(b) a%<<%b%//%a.leftShift(b) • Credit an account a%>>%b%//%a.rightShift(b) +a%%%%%//%a.unaryPlus() • account << 10.dollars account += 10.dollars fa%%%%%//%a.unaryMinus() account.credit 10.dollars ~a%%%%%//%a.bitwiseNegate() 58
  • 99. Operator overloading • Update the Distance class with a div() method following the naming convetion for operators class%Distance%{ %%%%... %%%%Speed%div(Duration%t)%{ %%%%%%%%new%Speed(this,%t) %%%%} %%%%... } 59
  • 100. Operator overloading • Update the Distance class with a div() method following the naming convetion for operators class%Distance%{ %%%%... %%%%Speed%div(Duration%t)%{ %%%%%%%%new%Speed(this,%t) %%%%} %%%%... } Optional return 59
  • 101. Equivalence of notation • Those two notations are actually equivalent: 2.km/h 2.getKm().div(h) 60
  • 102. Equivalence of notation • Those two notations are actually equivalent: 2.km/h This one might be slightly more verbose! 2.getKm().div(h) 60
  • 103. Named parameters usage move!left,!at:!3.km/h 61
  • 104. Named parameters usage move!left,!at:!3.km/h Normal parameter 61
  • 105. Named parameters usage move!left,!at:!3.km/h Normal Named parameter parameter 61
  • 106. Named parameters usage move!left,!at:!3.km/h Normal Named parameter parameter Will call: def!take(Map!m,!Direction!q) 61
  • 107. Named parameters usage move!left,!at:!3.km/h Normal Named parameter parameter Will call: def!take(Map!m,!Direction!q) All named parameters go into the map argument 61
  • 108. Named parameters usage move!left,!at:!3.km/h Normal Named parameter parameter Will call: def!take(Map!m,!Direction!q) All named parameters go Positional parameters into the map argument come afterwards 61
  • 109. Named parameters usage move!left,!at:!3.km/h 62
  • 110. Named parameters usage move!left,!at:!3.km/h Can we get rid of the comma? 62
  • 111. Named parameters usage move!left,!at:!3.km/h Can we get rid of What about the the comma? colon too? 62
  • 112. Command chains • A grammar improvement in Groovy 1.8 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) 63
  • 113. Command chains %move%left%%at%3.km/h% 64
  • 114. Command chains Alternation of method names %move%left%%at%3.km/h% 64
  • 115. Command chains Alternation of method names %move%left%%at%3.km/h% and parameters (even named ones) 64
  • 116. Command chains %move%left%%at%3.km/h% 64
  • 117. Command chains Equivalent to: %%%%%(%%%%).%%(%%%%%%) %move%left%%at%3.km/h% 64
  • 118. Look Ma! No par ens, no dots!
  • 119. Command chains //%Java%fluent%API%approach class%Robot%{ %%%%... $$$$def%move(Direction%dir)%{ %%%%%%%%this.dir%=%dir %%%%%%%%return%this %%%%} %%%%def%at(Speed%speed)%{ %%%%%%%%this.speed%=%speed %%%%%%%%return%this %%%%} %%%%... } 66
  • 120. Command chains def)move(Direction)dir)){ ))))[at:){)Speed)speed)F> ))))))))))))... ))))))))}] ))))}] } 67
  • 121. Command chains def)move(Direction)dir)){ ))))[at:){)Speed)speed)F> ))))))))))))... Nested maps ))))))))}] and closures ))))}] } 67
  • 122. Command chains def)move(Direction)dir)){ ))))[at:){)Speed)speed)F> ))))))))))))... Nested maps ))))))))}] and closures ))))}] } Usage in your DSLs move%left%at%3.km/h 67
  • 124. Command chains //%methods%with%multiple%arguments%(commas) 68
  • 125. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor 68
  • 126. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation 68
  • 127. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good 68
  • 128. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures 68
  • 129. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} 68
  • 130. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens 68
  • 131. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens select%all%%unique()%from%names 68
  • 132. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens select%all%%unique()%from%names //%possible%with%an%odd%number%of%terms 68
  • 133. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens select%all%%unique()%from%names //%possible%with%an%odd%number%of%terms deploy%left%%arm 68
  • 134. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%) //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens select%all%%unique()%from%names //%possible%with%an%odd%number%of%terms deploy%left%%arm 68
  • 135. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%) //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good %%%%%(%%%%%%%%%%%).%%%%%%(%%%%) //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} //%zerofarg%methods%require%parens select%all%%unique()%from%names //%possible%with%an%odd%number%of%terms deploy%left%%arm 68
  • 136. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%) //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good %%%%%(%%%%%%%%%%%).%%%%%%(%%%%) //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} %%%%%(%%).%%%%(%%).%%%%(%%) //%zerofarg%methods%require%parens select%all%%unique()%from%names //%possible%with%an%odd%number%of%terms deploy%left%%arm 68
  • 137. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%) //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good %%%%%(%%%%%%%%%%%).%%%%%%(%%%%) //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} %%%%%(%%).%%%%(%%).%%%%(%%) //%zerofarg%methods%require%parens select%all%%unique()%from%names %%%%%%(%%%).%%%%%%%%.%%%%(%%%%%) //%possible%with%an%odd%number%of%terms deploy%left%%arm 68
  • 138. Command chains //%methods%with%multiple%arguments%(commas) take%coffee%%with%sugar,%milk%%and%liquor %%%%(%%%%%%).%%%%(%%%%%%%%%%%).%%%(%%%%%%) //%leverage%namedfargs%as%punctuation check%that:%vodka%%tastes%good %%%%%(%%%%%%%%%%%).%%%%%%(%%%%) //%closure%parameters%for%new%control%structures given%{}%%when%{}%%then%{} %%%%%(%%).%%%%(%%).%%%%(%%) //%zerofarg%methods%require%parens select%all%%unique()%from%names %%%%%%(%%%).%%%%%%%%.%%%%(%%%%%) //%possible%with%an%odd%number%of%terms deploy%left%%arm %%%%%%(%%%%). 68
  • 140. Final result move!forward!at!3.km/h 69
  • 141. move forward at 3.km/h
  • 142. move forward at 3.km/h Yes! We did it!
  • 143. What about security and safety?
  • 144. Security and safety JVM Security Managers SecureASTCustomizer Sandboxing Controlling scripts execution 72
  • 145. Play it safe in a sandbox
  • 146. Playing it safe... • You have to think carefully about what DSL users are allowed to do with your DSL • Forbid things which are not allowed •leverage the JVM’s Security Managers • this might have an impact on performance •use a Secure AST compilation customizer • not so easy to think about all possible cases •avoid long running scripts with *Interrupt transformations 74
  • 147. Security Managers • Groovy is just a language leaving on the JVM, so you have access to the usual Security Managers mechanism • Nothing Groovy specific here • Please check the documentation on Security Managers and how to design policy files 75
  • 148. SecureASTCustomizer def!secure!=!new!SecureASTCustomizer() secure.with!{ //!disallow!closure!creation !!!closuresAllowed!=!false! //!disallow!method!definitions !!!methodDefinitionAllowed!=!false! //!empty!white!list!=>!forbid!certain!imports !!!importsWhitelist!=![...]! !!!staticImportsWhitelist!=![...] //!only!allow!some!static!import !!!staticStarImportsWhitelist!=![...] //!language!tokens!allowed !!!!tokensWhitelist!=![...] //!types!allowed!to!be!used !!!constantTypesClassesWhiteList!=![...] //!classes!who!are!allowed!to!be!receivers!of!method!calls !!!receiversClassesWhiteList!=![...] } def!config!=!new!CompilerConfiguration() config.addCompilationCustomizers(secure) def!shell!=!new!GroovyShell(config) 76
  • 149. 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 77
  • 150. @ThreadInterrupt @ThreadInterrupt import%groovy.transform.ThreadInterrupt% % while%(true)%{ %%%%//%Any%extraterestrial%around? } 78
  • 151. @ThreadInterrupt @ThreadInterrupt import%groovy.transform.ThreadInterrupt% % while%(true)%{ { %%%%if%(Thread.currentThread.isInterrupted()) %%%%%%%%throw$new%InterruptedException() } %%%%//%Any%extraterestrial%around? } 78
  • 152. @TimedInterrupt @TimedInterrupt(10) import!groovy.transform.TimedInterrupt! ! while!(true)!{ !!!!move!left !!!!//!circle!forever } • InterruptedException thrown when checks indicate code ran longer than desired 79
  • 153. @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({$battery.level$<$O.1$}) import%groovy.transform.ConditionalInterrupt 100.times%{%%%% %%%%move%forward%at%10.km/h } 80
  • 154. Using compilation customizers • In our previous three examples, the usage of the interrupts were explicit, and users had to type them • if they want to deplete the battery of your robot, they won’t use interrupts, so you have to impose interrupts yourself • With compilation customizers you can inject those interrupts thanks to the ASTTransformationCustomizer 81
  • 155. What have we learnt? 82
  • 156. Groovy Power!™ • A flexible and malleable syntax • scripts vs classes, optional typing, colons and parens • Groovy offers useful dynamic features for DSLs • operator overloading, ExpandoMetaClass • Can write almost plain natural language sentences • for readable, concise and expressive DSLs • Groovy DSLs are easy to integrate, and can be secured to run safely in your own sandbox 83
  • 157. Groovy Power!™ Groovy is a great fit for DSLs! • A flexible and malleable syntax • scripts vs classes, optional typing, colons and parens • Groovy offers useful dynamic features for DSLs • operator overloading, ExpandoMetaClass • Can write almost plain natural language sentences • for readable, concise and expressive DSLs • Groovy DSLs are easy to integrate, and can be secured to run safely in your own sandbox 83
  • 158. And there’s more! • We haven’t dived into... •How to implement your own control structures with the help of closures •How to create Groovy « builders » •How to hijack the Groovy syntax to develop our own language extensions with AST Transformations •Source preprocessing for custom syntax •How to use the other dynamic metaprogramming techniques available •How to improve error reporting with customizers •IDE support with DSL descriptors (GDSL and DSLD) 84
  • 159. Thank you! ge e Lafor lopment Gui llaum ovy Deve Head of Gro om @ gmail.c laforge rge Email: g @glafo o/glaforg e Twitter : http://gplus.t spot.com : G oogle+ //glaforge.app p: B log: htt 85
  • 160. Questions & Answers Got questions, really? 86
  • 161. Questions & Answers I might have answers! Got questions, really? 86
  • 162. Image credits • 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 • Russian flag: http://good-wallpapers.com/pictures/4794/Russian%20Flag.jpg • Space odissey: http://dearjesus.files.wordpress.com/2010/04/2001_a_space_odyssey_1.jpg • HAL red: http://2.bp.blogspot.com/-yjsyPxUFicY/TcazwAltOaI/AAAAAAAAAho/GVT7wGhnrUM/s1600/2001-a-space-odyssey-HAL.jpg • Back in time: http://4.bp.blogspot.com/-Pt44Dk9J2EM/TrQx9YNmVcI/AAAAAAAAAk4/ivWw9Lja05k/s1600/clocky.jpg • USSR Space posters: http://www.flickr.com/photos/justinvg • Russian General: http://rickrozoff.files.wordpress.com/2012/02/general-nikolai-makarov.jpg • Rocket: http://blog.al.com/breaking/2009/03/soyuz_launch.jpg • Progress capsule: http://www.spacedaily.com/images/progress-ocean-desk-1024.jpg • Buran: http://www.buran.fr/mriya-antonov/Photos//050-Exhibition%20au%20Bourget%20avec%20Bourane-Airshow%20with%20Buran%20at%20Le%20Bourget-1134884.jpg • Man in space: http://vintagespace.files.wordpress.com/2010/11/voskhod-2_leonov.jpg • Sputnik 2: http://launiusr.files.wordpress.com/2010/06/sputnik2.jpg • Lunakod: http://www.astr.ua.edu/keel/space/lunakhod_moscow.jpg • Sandbox: http://www.turnbacktogod.com/wp-content/uploads/2008/09/sandbox.jpg • Repair: http://www.oneangels.com/wp-content/uploads/2012/03/repair1.jpg • Mars rover: http://wallpapers.free-review.net/wallpapers/49/Mars_rover%2C_Mars_-_03.jpg • Mars rover 2: http://www.universetoday.com/wp-content/uploads/2011/06/551038main_pia14156-43_946-710.jpg • Thumb: http://www.wpclipart.com/sign_language/thumbs_up_large.png.html • Night sky: http://www.aplf-planetariums.info/galeries/ciel_profond/2004-07-01-Voie_Lactee_Scorpion-Jean-Luc_PUGLIESI.jpg • Obama yes we can: http://www.dessinemoiunboulon.net/wp-content/uploads/2009/01/obama-yes-we-can_04-nov-08.jpg • Hook: http://winningware.com/blog/wp-content/uploads/2009/12/FishHookXSmall.jpg • HP 48 GX: http://calculators.torensma.net/files/images/hewlett-packard_hp-48g.jpg • Omer: http://www.irmin.com/wallpaper/TV/Homer%20Simpson%20Oh%20No.jpg • Cadenat: http://acsgsecurite.com/upl/site/cadenat.png 87