SlideShare a Scribd company logo
1 of 79
Download to read offline
Design Your Own Domain-Specific Language
    with Groovy!
    Guillaume Laforge
    Groovy Project Manager




                                     © 2010 SpringSource, A division of VMware. All rights reserved

lundi 22 mars 2010
Guillaume Laforge

    • Groovy Project Manager
    • JSR-241 Spec Lead

    • Head of Groovy Development
      at SpringSource / VMWare
    • Initiator of the Grails framework

    • Co-author of Groovy in Action


    • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The
       Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC,
       and more...




                                                                          2

lundi 22 mars 2010
Groovy in a few words


    ! Groovy is a dynamic language for the JVM
       • with a Meta Object Protocol
       • compiles directly to bytecode
       • provides seamless Java interoperability


    ! Groovy was created in 2003, is hosted at Codehaus, and is under the
       Apache license


    ! Relaxed grammar deriving from Java 5
       • annotations, generics, static imports, enums, varargs...
       • borrowed good ideas from Ruby, Python, Smalltalk
       • flat learning curve for Java developers




                                                                            3

lundi 22 mars 2010
The Context




lundi 22 mars 2010
Subject Matter Expers,
      Business Analysts...
lundi 22 mars 2010
Developer producing LOLCODE




  HAI
  CAN HAS STDIO?
  I HAS A VAR
  IM IN YR LOOP
     UP VAR!!1
     VISIBLE VAR
     IZ VAR BIGGER THAN 10? KTHXBYE
  IM OUTTA YR LOOP
  KTHXBYE
lundi 22 mars 2010
Lots of Languages...




lundi 22 mars 2010
And in the end...
                     nobody understands
                              each other
lundi 22 mars 2010
Expressing Requirements...




                                 9

lundi 22 mars 2010
DSL: a potential solution?

    !Use a more expressive language
     than a general purpose one
    !Share a common metaphore 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
    !Cleanly separate business logic from application code
    !Let business rules have their own lifecycle




                                                             10

lundi 22 mars 2010
Towards more readibility (1)




                                   11

lundi 22 mars 2010
Towards more readibility (1)




                                   11

lundi 22 mars 2010
Towards more readibility (1)




                                   20%




                                         11

lundi 22 mars 2010
Towards more readibility (2)




                                   12

lundi 22 mars 2010
Towards more readibility (2)




                                   12

lundi 22 mars 2010
Towards more readibility (2)




                                   80%



                                         12

lundi 22 mars 2010
A collection of DSLs


    ! In our everyday life, we’re surrounded by DSLs

       • Technical dialects
       • Notations
       • Business languages




                                                       13

lundi 22 mars 2010
Technical dialects




                         14

lundi 22 mars 2010
SQL




lundi 22 mars 2010
^[w-.]+@([w-]){2,4}$




                                               16

lundi 22 mars 2010
Notations




                     17

lundi 22 mars 2010
1. e4 e5
    2. Nf3 Nc6
    3. Bb5 a6



lundi 22 mars 2010
L2          U   F-1   B   L2   F   B -1   U   L2

lundi 22 mars 2010
Visual!




lundi 22 mars 2010
Real-life Groovy examples


    ! Anti-malaria drug resistance simulation
    ! Human Resources employee skills representation
    ! Insurance policies risk calculation engine
    ! Loan acceptance rules engine for a financial platform
    ! Mathematica-like lingua for nuclear safety simulations
    ! Market data feeds evolution scenarios

    ! and more...




                                                               21

lundi 22 mars 2010
Three levels of techniques




   Flexible &               Meta-
   malleable syntax         programming          AST
                                                 transformations
  • scripts                 • POGO
  • optional typing         • categories         • AST traversal
  • native syntax           • builders           • local transformations
  constructs                • custom MetaClass   • global transformations
  • parens / semi           • ExpandoMetaClass   • hooks into Antlr
  ommission
  • named arguments
  • BigDecimal
  • operator overloading
  • closures



                                                                      22

lundi 22 mars 2010
A flexible & malleable syntax


    ! No need to write full-blown classes, use scripts
    ! Optional typing (def)
       • in scripts, you can even omit the def keyword
    ! Native syntax constructs
    ! Parentheses & semi-colons are optional
    ! Named arguments
    ! BigDecimal by default for decimal numbers
    ! Closures for custom control structures
    ! Operator overloading




                                                         23

lundi 22 mars 2010
Scripts vs classes



      ! Hide all the boilerplate technical code
         • an end-user doesn’t need to know about classes


                     public class Rule {
                                                               ) {
                         public static void main(String[] args
                             System.out.println(“Hello”);
                         }
                     }


                     println “Hello”




                                                                     24

lundi 22 mars 2010
Optional typing



      ! No need to bother with types or even generics
         • unless you want to!

      ! Imagine an interest rate lookup table method returning some
         generified type:


                Rate <LoanType, Duration, BigDecimal>[]
                     lookupTable() { ... }
                def table = lookupTable()

      ! No need to repeat the horrible generics type info!




                                                                      25

lundi 22 mars 2010
Native syntax constructs
    ! Lists
                        [Monday, Tuesday, Wednesday]

    ! Maps
                     [CA: ‘California’, TX: ‘Texas’]

    ! Ranges



       • You can create your own custom ranges

                     def bizDays = Monday..Friday
                     def allowedAge = 18..65



                                                       26

lundi 22 mars 2010
Optional parens & semis
    ! Make statements and expressions
       look more like natural languages




                         move(left);




                         move left




                                          27

lundi 22 mars 2010
Named arguments
    ! In Groovy you can mix named and unnamed arguments for method
       parameters
       • named params are actually put in a map parameter
       • plus optional parens & semis


                             take 1.pill,
                              of: Chloroquinine,
                           after: 6.hours

    ! Corresponds to a method signature like:

                 def t ake(Map m, MedicineQuantity mq)




                                                                     28

lundi 22 mars 2010
BigDecimal by default



    ! Main reason why financial institutions often decide to use Groovy for
       their business rules!
       • Although these days rounding issues are overrated!


    ! Java vs Groovy for a simple interpolation equation
         BigDecimal uMinusv = c.subtract(a);
         BigDecimal vMinusl = b.subtract(c);
         BigDecimal uMinusl = a.subtract(b);
         return e.multiply(uMinusv)
                   .add(d.multiply(vMinusl))
                                                          _HALF_UP);
                    .divide(uMinusl, 10, BigDecimal.ROUND




                     (d * (b - c) + e * (c - a)) / (a - b)



                                                                              29

lundi 22 mars 2010
Custom control structures,
    thanks to closures
    ! When closures are last, they can be put “out” of the parentheses
       surrounding parameters

                unless (a ccount.balance > 100.euros,
                    { account.debit 100.euros })


                unless (a ccount.balance > 100.euros) {
                    account.debit 100.euros
                }

    ! Signature

                     de f unless(boolean b, Closure c)



                                                                         30

lundi 22 mars 2010
Operator overloading


    a + b            a.plus(b)
                                         • Currency amounts
    a - b            a.minus(b)               15.euros + 10.dollars
    a * b            a.multiply(b)
    a / b            a.divide(b)         • Distance handling
    a % b            a.modulo(b)
    a ** b           a.power(b)             10.kilometers - 10.meters
    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
    -a               a.unaryMinus()         account += 10.dollars
    ~a               a.bitwiseNegate()
                                            account.credit 10.dollars


                                                                        31

lundi 22 mars 2010
The MOP
    (Meta-Object Protocol)




lundi 22 mars 2010
Groovy’s MOP
    ! All the accesses to methods, properties, constructors, operators, etc.
      can be intercepted thanks to the MOP
    ! While Java’s behavior is hard-wired at compile-time in the class
    ! Groovy’s runtime behavior is adaptable at runtime through the
      metaclass
    ! Different hooks for changing the runtime behavior
       • GroovyObject, custom MetaClass implementation, categories, ExpandoMetaClass




                                                                                       33

lundi 22 mars 2010
GroovyObject



      ! All instances of classes created in Groovy implement the
         GroovyObject interface:

               get/setProperty(String name)
               invokeMeth od(String name, Object[] params)
               propertyMissing(String name)
               methodMissing( String name, Object[] params)
                get/setMetaClass(MetaClass mc)



      ! A GO can have “pretended” methods and properties


                                                                   34

lundi 22 mars 2010
MetaClass
    ! The core of Groovy’s MOP system

                     invokeConstructor()
                     invokeMe thod() and invokeStaticMethod()
                     invokeMissingMethod()
                     getProperty() and setProperty()
                     ge tAttribute() and setAttribute()
                     respondsTo() and hasProperty()



    ! MetaClasses can change the behavior of existing third-party classes
       — even from the JDK



                                                                            35

lundi 22 mars 2010
ExpandoMetaClass
    ! A DSL for MetaClasses!

                MoneyAmount.meta Class.constructor = { ... }
                Numb er.metaClass.getDollars = { ... }
                Di stance.metaClass.toMeters = { ... }
                Distance .metaClass.static.create = { ... }


    ! To avoid repetition of Type.metaClass, you can pass a closure to
       metaClass { ... }

    ! The delegate variable in closure represents the current instance,
       and it the default parameter




                                                                          36

lundi 22 mars 2010
The Builder pattern



lundi 22 mars 2010
A builder for HR



       softskills {
           ideas {
                capture 2
                formulate 3
           }
           ...
       }
       knowhow {
           languages {
                java 4
                groovy 5
           }
            ...
        }




                              38

lundi 22 mars 2010
A builder for HR



       softskills {
           ideas {
                capture 2
                formulate 3
           }
           ...
       }
       knowhow {
           languages {
                java 4
                groovy 5
           }
            ...
        }




                              38

lundi 22 mars 2010
Builders



! Builders are...
   • a mechanism for creating any tree-structered graph
   • the realization of the GoF builder pattern at the syntax level in Groovy
   • simply a clever use of chained method invocation, closures, parentheses omission, and use
     of the GroovyObject methods


! Existing builders
   • XML, Object graph, Swing, Ant, JMX, and more...




                                                                                          39

lundi 22 mars 2010
The clever trick
    ! GroovyObject#invokeMethod() is used to catch all non-existing
      method calls in the context of the builder
    ! The nesting of closures visually shows the level of nesting / depth in
      the tree
    ! builder.m1(attr1:1, attr2:2, { builder.m2(..., {...}) }
       becomes equivalent to
       builder.m1(attr1:1, attr2:2) { m2(...) {...} }

       thanks to parens omission




                                                                               40

lundi 22 mars 2010
Adding properties to numbers
    ! Three possible approaches

       • create a Category
          • a category is a kind of decorator for default MCs

       • create a custom MetaClass
          • a full-blown MC class to implement and to set on the POGO instance

       • use ExpandoMetaClass
          • friendlier DSL approach but with a catch




                                                                                 41

lundi 22 mars 2010
With a Category



               class DistanceCategory {
                   static Di stance getMeters(Integer self) {
                       new Distance(self, Unit.METERS)
                   }
               }

               use(DistanceCategory) {
                   100.meters
               }



      ! Interesting scope: thread-bound & lexical
      ! Have to surround with “use”
         • but there are ways to hide it



                                                                42

lundi 22 mars 2010
With an ExpandoMetaClass



               Number.metaClass.getMeters = {->
                   new Distance(delegate, Unit.METERS)
               }

               100.meters


      ! Works for the class hierarchy for POJOs, and a flag exists to make it
         work for POGOs too

      ! But the catch is it’s really a global change, so beware EMC
         enhancements collisions




                                                                                43

lundi 22 mars 2010
Compile-time Metaprogramming


    ! Groovy 1.6 introduced AST Transformations

    ! Compile-time == No runtime performance penalty!




                                 Transformation




                                                        44

lundi 22 mars 2010
Compile-time metaprogramming
    ! With metaprogramming, Groovy’s able to modify the behaviour of
       programs... at runtime

    ! Groovy 1.6 introduced AST Transformations
       • AST: Abstract Syntax Tree
       • Ability to change what’s being compiled at compile-time!
          • No runtime impact!
          • Lets you change the semantics of your programs!
          • Nice way of implementing patterns and removing boiler-plate technical code


    ! Two kinds of transformations: global and local




                                                                                         45

lundi 22 mars 2010
AST Transformations
    ! Two kinds of transformations

       • Global transformations
          • applicable to all compilation units

       • Local transformations
          • applicable to marked program elements
          • using specific marker annotations




                                                    46

lundi 22 mars 2010
AST Transformations
    in Groovy 1.6
    ! Several (local) transformations finds their way
       • @Singleton — okay, not really a pattern :-)
       • @Immutable, @Lazy, @Delegate
       •@Newify
       • @Category and @Mixin
       •@PackageScope
       • Swing’s @Bindable and @Vetoable
       • Grape’s @Grab

    ! Let’s have a look at some of them




                                                        47

lundi 22 mars 2010
The @Singleton anti-pattern


    !The evil Java singleton

                     public class Evil {                                ;
                         public st atic final Evil instance = new Evil()
                         privavte Evil() {}
                                                              ; }
                         Evil getInstance() { return instance
                     }


    !In Groovy now:
                               @Singleton class Evil {}

    !A lazy version also:
                        @Singleton(lazy = true) class Evil {}




                                                                            48

lundi 22 mars 2010
@Immutable
    ! To properly implement immutable classes
       • No mutators (state musn’t change)
       • Private final fields
       • Defensive copying of mutable components
       • Proper equals() / hashCode() / toString() for comparisons, or for keys in maps,
          etc.




             @Immutable class Coordinates {
                 Double lat, lng
             }
             def c1 = new Coordinates(lat: 48.8, lng: 2.5)
             def c2 = new Coordinates(48.8, 2.5)
             assert c1 == c2



                                                                                      49

lundi 22 mars 2010
@Lazy, not just for lazy dudes!
    ! When you need to lazily evaluate or instantiate complex data
       structures for class fields, mark them with the @Lazy annotation


                     class Dude {
                         @Lazy pets = retrieveFromSlowDB()
                     }


    ! Groovy will handle the boiler-plate code for you!




                                                                          50

lundi 22 mars 2010
@Delegate
    Not just for managers!
    !You can delegate to fields of your class
       •Think multiple inheritance

                     class Employee {
                         def doTheWork() { "done" }
                     }
                     class Manager {
                                                               ee()
                         @Delegate Employee slave = new Employ
                     }
                     def god = new Manager()
                     assert god.doTheWork() == "done"



    !Damn manager will get all the praise...




                                                                      51

lundi 22 mars 2010
Global transformations
    ! Implement ASTTransformation
    ! Annotate the transfo specifying a compilation phase

                                                                       ERSION)
                     @GroovyASTTr ansformation(phase=CompilePhase.CONV
                     public class MyTransformation
                         implements ASTTransformation {
                                                                    Unit unit)
                         publ ic void visit(ASTNode[] nodes, Source
                         { ... }
                     }




    ! For discovery, create the file META-INF/services/
      org.codehaus.groovy.transform.ASTTransformation
    ! Add the fully qualified name of the class in that file




                                                                                 52

lundi 22 mars 2010
Local transformations
    ! Same approach as Globale transformations
    ! But you don’t need the META-INF file
    ! Instead create an annotation to specify on which element the
       transformation should apply



                     @Ret ention(RetentionPolicy.SOURCE)
                     @Target([ElementType.METHOD])
                     @GroovyASTTransformationClass(
                          ["fqn.MyTransformation"])
                     publ ic @interface WithLogging {...}




                                                                     53

lundi 22 mars 2010
Example: the Spock framework
    ! Changing the semantics of the original code
    ! But keeping a valid Groovy syntax

                     @Speck
                     class HelloSpock {
                                                                  () {
                         def "can you figure out what I'm up to?"
                             expect:
                             name.size() == size

                             where:
                             name << ["Kirk", "Spock", "Scotty"]
                             size << [4, 5, 6]
                         }
                     }



    ! Check out http://www.spockframework.org



                                                                         54

lundi 22 mars 2010
Various integration mechanisms
    ! Java 6’s javax.script.* APIs (aka JSR-223)
    ! Spring’s language namespace
    ! Groovy’s own mechanisms

    ! But a key idea is to externalize those DSL programs
       • DSL programs can have their own lifecycle
       • no need to redeploy an application because of a rule change
       • business people won’t see the technical code




                                                                       55

lundi 22 mars 2010
Java 6’s javax.script.* API



      ! Groovy 1.6 provides its own implementation of the javax.script.* API



                     ScriptEngineManager mgr =
                             new ScriptEngineManager();
                     ScriptEngine engine =
                             mgr.getEngineByName(“Groovy”);

                     String result =
                     (String)engine.eval(“2+3”);




                                                                               56

lundi 22 mars 2010
Spring’s lang namespace



      ! POGOs (Plain Old Groovy Objects) can be pre-compiled as any
        POJO and used interchangeably with POJOs in a Spring application
      ! But Groovy scripts & classes can be loaded at runtime through the
        <lang:groovy/> namespace and tag
      ! Reloadable on change
      ! Customizable through a custom MetaClass



          <lang:groovy id="events"                         ovy"
              script-s ource="classpath:dsl/eventsChart.gro
              customizer-ref="eventsMetaClass" />




                                                                            57

lundi 22 mars 2010
Groovy’s own mechanisms
    ! Eval
       • for evaluating simple expressions

    ! GroovyShell
       • for more complex scripts and DSLs

    ! GroovyClassLoader
       • the most powerful mechanism




                                             58

lundi 22 mars 2010
Eval



      ! Simple mechanism to evaluate math-like formulas




                     Eval.me (           ‘3*4’)
                     Eval.x (1,          ‘3*x + 4’)
                     Eval.xy (1, 2,      ‘x + y’)
                     Eval.xyz(1, 2, 3,   ‘x * y - z’)




                                                          59

lundi 22 mars 2010
GroovyShell



      ! A Binding provides a context of execution
         • can implement lazy evaluation if needed



      ! A base script class can be specified


           def binding = new Binding()
           binding.mass = 22.3
           binding.velocity = 10.6
           def shell = new GroovyShell(binding)
           shell. evaluate(“mass * velocity ** 2 / 2”)




                                                         60

lundi 22 mars 2010
GroovyClassLoader



      ! Most powerful mechanism
         • could also visit or change the AST
         • scripts & classes can be loaded from elsewhere
         • more control on compilation



                     GroovyClassLoader gcl =
                             new GroovyClassLoader();
                     Class clazz = gcl.parseClass(
                             new File(“f.groovy”));
                     GroovyObject instance =
                             (GroovyObject)clazz.newInstance();
                     instance.setMetaClass(customMC);




                                                                  61

lundi 22 mars 2010
Externalize business rules
    ! Although Groovy DSLs can be embedded in normal Groovy classes,
       you should externalize them

    ! Store them elsewhere
       • in a database, an XML file, etc.

    ! Benefits
       • Business rules are not entangled
         in technical application code
       • Business rules can have their own lifecycle, without requiring application
         redeployments




                                                                                      62

lundi 22 mars 2010
A few considerations




                           63

lundi 22 mars 2010
Start small, with key concepts
     Beware over-engineering!




lundi 22 mars 2010
Grow your language
                           progressively
lundi 22 mars 2010
Get your hands dirty
                     Play with the end-users

lundi 22 mars 2010
Let your DSL fly,
    it’s not yours, it’s theirs!




lundi 22 mars 2010
Tight feedback loop
     Iterative process




lundi 22 mars 2010
Stay humble,
   You can’t get it right the 1st time.




     Don’t design alone at your desk
     Involve the end users from the start
lundi 22 mars 2010
Playing it safe in a sandbox
lundi 22 mars 2010
Various levels
    of sandboxing




    ! Groovy supports the usual
       Java Security Managers

    ! Use metaprogramming tricks to prevent calling / instanciating certain
       classes

    ! Create a special GroovyClassLoader AST code visitor to filter only the
       nodes of the AST you want to keep
       • ArithmeticShell in Groovy’s samples




                                                                           71

lundi 22 mars 2010
Test, test, test!


    ! Don’t just test for nominal cases
       • Explicitely test for errors!

    ! Ensure end-users get meaninful error messages




                                                      72

lundi 22 mars 2010
Question & Answers




                         73

lundi 22 mars 2010
Picture credits


         http://www.flickr.com/photos/featheredtar/2305070061/                 http://commons.wikimedia.org/wiki/File:Platypus.jpg

         http://www.thedailygreen.com/cm/thedailygreen/images/WT/christmas-    http://www.flickr.com/photos/joaomoura/2317171808/sizes/l/
         tree-with-gifts-flipbook.jpg
                                                                               http://www.flickr.com/photos/wiccked/132687067/
         http://www.flickr.com/photos/chicoer2001/188468490/
                                                                               http://www.flickr.com/photos/timsamoff/252370986/sizes/l/
         http://www.flickr.com/photos/olibac/4054644737/                       http://www.flickr.com/photos/29738009@N08/2975466425/sizes/l/
         http://www.flickr.com/photos/epsos/3384297473/                        http://www.flickr.com/photos/howie_berlin/180121635/sizes/o/
         http://media.techeblog.com/images/clapboard.jpg (clap)                http://www.flickr.com/photos/yogi/1281980605/sizes/l/

         http://www.flickr.com/photos/diegocupolo/3614879332/ (flower power)   http://www.flickr.com/photos/dorseygraphics/1336468896/sizes/l/

         http://www.flickr.com/photos/oskay/237442629/sizes/m/ (danger)        http://www.flickr.com/photos/xcbiker/386876546/sizes/l/

         http://www.partybox.co.uk/data/partyimages/                           http://www.flickr.com/photos/pietel/152403711/sizes/o/
         250x250/6ftcutoutaustinpowers.jpg (austin powers)
                                                                               http://www.flickr.com/photos/forezt/192554677/sizes/o/
         http://www.flickr.com/photos/27663074@N07/3413698337/ (jeepers
         creepers)                                                             http://keremkosaner.files.wordpress.com/2008/04/softwaredevelopment.gif

         http://www.flickr.com/photos/wheatfields/420088151/sizes/l/           http://www.jouy.inra.fr

         http://www.flickr.com/photos/therefromhere/518053737/sizes/l/         http://www.flickr.com/photos/ejpphoto/408101818/sizes/o/

         http://www.flickr.com/photos/romainguy/230416692/sizes/l/             http://www.flickr.com/photos/solaro/2127576608/sizes/l/

         http://www.flickr.com/photos/addictive_picasso/2874279971/sizes/l/    http://www.flickr.com/photos/biggreymare/2846899405/sizes/l/

         http://www.flickr.com/photos/huangjiahui/3127634297/sizes/l/          http://www.flickr.com/photos/wwworks/2222523978/ (earth)

         http://www.flickr.com/photos/25831000@N08/3064515804/sizes/o/         http://static-p3.fotolia.com/jpg/
                                                                               00/01/64/30/400_F_1643044_YrBQoPnt0SC5gHAueG0bhx20yCSL42.jpg (trafic
                                                                               light)
         http://www.flickr.com/photos/lanier67/3147696168/sizes/l/
                                                                               http://aldaria02.a.l.pic.centerblog.net/lz2levrz.jpg (griffon)
         http://www.flickr.com/photos/ktb/4916063/sizes/o/
                                                                               http://www.flickr.com/photos/geishaboy500/104137788/ (soap)
         http://www.flickr.com/photos/nathonline/918128338/sizes/l/
                                                                               Matriochka http://lang.russe.free.fr/images/matriochka.jpg
         http://www.flickr.com/photos/kevinsteele/39300193/sizes/l/

         http://commons.wikimedia.org/wiki/File:Brueghel-tower-of-babel.jpg




                                                                                                                                                         74

lundi 22 mars 2010

More Related Content

Similar to Implementing Groovy Domain-Specific Languages - S2G Forum - Munich 2010

Bar Camp Auckland - Mongo DB Presentation BCA4
Bar Camp Auckland - Mongo DB Presentation BCA4Bar Camp Auckland - Mongo DB Presentation BCA4
Bar Camp Auckland - Mongo DB Presentation BCA4John Ballinger
 
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...TAUS - The Language Data Network
 
Idiomatic Domain Driven Design: implementing CQRS
Idiomatic Domain Driven Design: implementing CQRSIdiomatic Domain Driven Design: implementing CQRS
Idiomatic Domain Driven Design: implementing CQRSAndrea Saltarello
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expertPaul King
 
Domain-driven Design
Domain-driven DesignDomain-driven Design
Domain-driven DesignAltoros
 
Practical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in GroovyPractical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in GroovyGuillaume Laforge
 
Intro To MongoDB
Intro To MongoDBIntro To MongoDB
Intro To MongoDBAlex Sharp
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseAndrew Eisenberg
 
GR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL SupportGR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL SupportGR8Conf
 
Go, Docker & Kubernetes
Go, Docker &  KubernetesGo, Docker &  Kubernetes
Go, Docker & KubernetesGlobant
 
Best Practices in Ext GWT
Best Practices in Ext GWTBest Practices in Ext GWT
Best Practices in Ext GWTSencha
 
MongoDB is the new MySQL
MongoDB is the new MySQLMongoDB is the new MySQL
MongoDB is the new MySQLradamanthus
 
Nuxeo World Session: Semantic Technologies - Update on Recent Research
Nuxeo World Session: Semantic Technologies - Update on Recent ResearchNuxeo World Session: Semantic Technologies - Update on Recent Research
Nuxeo World Session: Semantic Technologies - Update on Recent ResearchNuxeo
 
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...David Beazley (Dabeaz LLC)
 
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)Moaid Hathot
 
Chatbots - A CMD for Humans (Ort Braude 2018)
Chatbots - A CMD for Humans (Ort Braude 2018)Chatbots - A CMD for Humans (Ort Braude 2018)
Chatbots - A CMD for Humans (Ort Braude 2018)Moaid Hathot
 

Similar to Implementing Groovy Domain-Specific Languages - S2G Forum - Munich 2010 (20)

Bar Camp Auckland - Mongo DB Presentation BCA4
Bar Camp Auckland - Mongo DB Presentation BCA4Bar Camp Auckland - Mongo DB Presentation BCA4
Bar Camp Auckland - Mongo DB Presentation BCA4
 
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...
TAUS OPEN SOURCE MACHINE TRANSLATION SHOWCASE, Monaco, Serge Gladhoff, Logrus...
 
Idiomatic Domain Driven Design: implementing CQRS
Idiomatic Domain Driven Design: implementing CQRSIdiomatic Domain Driven Design: implementing CQRS
Idiomatic Domain Driven Design: implementing CQRS
 
groovy DSLs from beginner to expert
groovy DSLs from beginner to expertgroovy DSLs from beginner to expert
groovy DSLs from beginner to expert
 
Základy GWT
Základy GWTZáklady GWT
Základy GWT
 
Domain-driven Design
Domain-driven DesignDomain-driven Design
Domain-driven Design
 
Practical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in GroovyPractical Domain-Specific Languages in Groovy
Practical Domain-Specific Languages in Groovy
 
Intro To MongoDB
Intro To MongoDBIntro To MongoDB
Intro To MongoDB
 
Better DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-EclipseBetter DSL Support for Groovy-Eclipse
Better DSL Support for Groovy-Eclipse
 
GR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL SupportGR8Conf 2011: STS DSL Support
GR8Conf 2011: STS DSL Support
 
Practical Groovy DSL
Practical Groovy DSLPractical Groovy DSL
Practical Groovy DSL
 
(not= DSL macros)
(not= DSL macros)(not= DSL macros)
(not= DSL macros)
 
Go, Docker & Kubernetes
Go, Docker &  KubernetesGo, Docker &  Kubernetes
Go, Docker & Kubernetes
 
Best Practices in Ext GWT
Best Practices in Ext GWTBest Practices in Ext GWT
Best Practices in Ext GWT
 
MongoDB is the new MySQL
MongoDB is the new MySQLMongoDB is the new MySQL
MongoDB is the new MySQL
 
Nuxeo World Session: Semantic Technologies - Update on Recent Research
Nuxeo World Session: Semantic Technologies - Update on Recent ResearchNuxeo World Session: Semantic Technologies - Update on Recent Research
Nuxeo World Session: Semantic Technologies - Update on Recent Research
 
20161014IROS_WS
20161014IROS_WS20161014IROS_WS
20161014IROS_WS
 
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...
Why Extension Programmers Should Stop Worrying About Parsing and Start Thinki...
 
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)
Chatbots - A CMD for Humans (Global Azure Bootcamp 2018, Tel-Aviv, Israel)
 
Chatbots - A CMD for Humans (Ort Braude 2018)
Chatbots - A CMD for Humans (Ort Braude 2018)Chatbots - A CMD for Humans (Ort Braude 2018)
Chatbots - A CMD for Humans (Ort Braude 2018)
 

More from Guillaume Laforge

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Guillaume Laforge
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Guillaume Laforge
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Guillaume Laforge
 
Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Guillaume Laforge
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Guillaume Laforge
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Guillaume 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 2012Guillaume 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 2012Guillaume Laforge
 
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGroovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume Laforge
Groovy 2.0 update - Cloud Foundry Open Tour Moscow - Guillaume LaforgeGuillaume Laforge
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGuillaume Laforge
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Guillaume Laforge
 
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 2011Guillaume 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 2011Guillaume Laforge
 
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Gaelyk update - Guillaume Laforge - SpringOne2GX 2011
Gaelyk update - Guillaume Laforge - SpringOne2GX 2011Guillaume Laforge
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Guillaume Laforge
 

More from Guillaume Laforge (20)

Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013Lift off with Groovy 2 at JavaOne 2013
Lift off with Groovy 2 at JavaOne 2013
 
Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013Groovy workshop à Mix-IT 2013
Groovy workshop à Mix-IT 2013
 
Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013Les nouveautés de Groovy 2 -- Mix-IT 2013
Les nouveautés de Groovy 2 -- Mix-IT 2013
 
Groovy 2 and beyond
Groovy 2 and beyondGroovy 2 and beyond
Groovy 2 and beyond
 
Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012Groovy 2.0 update at Devoxx 2012
Groovy 2.0 update at Devoxx 2012
 
Groovy 2.0 webinar
Groovy 2.0 webinarGroovy 2.0 webinar
Groovy 2.0 webinar
 
Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012Groovy Domain Specific Languages - SpringOne2GX 2012
Groovy Domain Specific Languages - SpringOne2GX 2012
 
Groovy 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
 
Going to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific LanguagesGoing to Mars with Groovy Domain-Specific Languages
Going to Mars with Groovy Domain-Specific Languages
 
Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012Groovy 2.0 - Devoxx France 2012
Groovy 2.0 - Devoxx France 2012
 
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...
 

Implementing Groovy Domain-Specific Languages - S2G Forum - Munich 2010

  • 1. Design Your Own Domain-Specific Language with Groovy! Guillaume Laforge Groovy Project Manager © 2010 SpringSource, A division of VMware. All rights reserved lundi 22 mars 2010
  • 2. Guillaume Laforge • Groovy Project Manager • JSR-241 Spec Lead • Head of Groovy Development at SpringSource / VMWare • Initiator of the Grails framework • Co-author of Groovy in Action • Speaker: JavaOne, QCon, JavaZone, Sun TechDays, Devoxx, The Spring Experience, SpringOne, JAX, Dynamic Language World, IJTC, and more... 2 lundi 22 mars 2010
  • 3. Groovy in a few words ! Groovy is a dynamic language for the JVM • with a Meta Object Protocol • compiles directly to bytecode • provides seamless Java interoperability ! Groovy was created in 2003, is hosted at Codehaus, and is under the Apache license ! Relaxed grammar deriving from Java 5 • annotations, generics, static imports, enums, varargs... • borrowed good ideas from Ruby, Python, Smalltalk • flat learning curve for Java developers 3 lundi 22 mars 2010
  • 5. Subject Matter Expers, Business Analysts... lundi 22 mars 2010
  • 6. Developer producing LOLCODE HAI CAN HAS STDIO? I HAS A VAR IM IN YR LOOP UP VAR!!1 VISIBLE VAR IZ VAR BIGGER THAN 10? KTHXBYE IM OUTTA YR LOOP KTHXBYE lundi 22 mars 2010
  • 8. And in the end... nobody understands each other lundi 22 mars 2010
  • 9. Expressing Requirements... 9 lundi 22 mars 2010
  • 10. DSL: a potential solution? !Use a more expressive language than a general purpose one !Share a common metaphore 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 !Cleanly separate business logic from application code !Let business rules have their own lifecycle 10 lundi 22 mars 2010
  • 11. Towards more readibility (1) 11 lundi 22 mars 2010
  • 12. Towards more readibility (1) 11 lundi 22 mars 2010
  • 13. Towards more readibility (1) 20% 11 lundi 22 mars 2010
  • 14. Towards more readibility (2) 12 lundi 22 mars 2010
  • 15. Towards more readibility (2) 12 lundi 22 mars 2010
  • 16. Towards more readibility (2) 80% 12 lundi 22 mars 2010
  • 17. A collection of DSLs ! In our everyday life, we’re surrounded by DSLs • Technical dialects • Notations • Business languages 13 lundi 22 mars 2010
  • 18. Technical dialects 14 lundi 22 mars 2010
  • 20. ^[w-.]+@([w-]){2,4}$ 16 lundi 22 mars 2010
  • 21. Notations 17 lundi 22 mars 2010
  • 22. 1. e4 e5 2. Nf3 Nc6 3. Bb5 a6 lundi 22 mars 2010
  • 23. L2 U F-1 B L2 F B -1 U L2 lundi 22 mars 2010
  • 25. Real-life Groovy examples ! Anti-malaria drug resistance simulation ! Human Resources employee skills representation ! Insurance policies risk calculation engine ! Loan acceptance rules engine for a financial platform ! Mathematica-like lingua for nuclear safety simulations ! Market data feeds evolution scenarios ! and more... 21 lundi 22 mars 2010
  • 26. Three levels of techniques Flexible & Meta- malleable syntax programming AST transformations • scripts • POGO • optional typing • categories • AST traversal • native syntax • builders • local transformations constructs • custom MetaClass • global transformations • parens / semi • ExpandoMetaClass • hooks into Antlr ommission • named arguments • BigDecimal • operator overloading • closures 22 lundi 22 mars 2010
  • 27. A flexible & malleable syntax ! No need to write full-blown classes, use scripts ! Optional typing (def) • in scripts, you can even omit the def keyword ! Native syntax constructs ! Parentheses & semi-colons are optional ! Named arguments ! BigDecimal by default for decimal numbers ! Closures for custom control structures ! Operator overloading 23 lundi 22 mars 2010
  • 28. Scripts vs classes ! Hide all the boilerplate technical code • an end-user doesn’t need to know about classes public class Rule { ) { public static void main(String[] args System.out.println(“Hello”); } } println “Hello” 24 lundi 22 mars 2010
  • 29. Optional typing ! No need to bother with types or even generics • unless you want to! ! Imagine an interest rate lookup table method returning some generified type: Rate <LoanType, Duration, BigDecimal>[] lookupTable() { ... } def table = lookupTable() ! No need to repeat the horrible generics type info! 25 lundi 22 mars 2010
  • 30. Native syntax constructs ! Lists [Monday, Tuesday, Wednesday] ! Maps [CA: ‘California’, TX: ‘Texas’] ! Ranges • You can create your own custom ranges def bizDays = Monday..Friday def allowedAge = 18..65 26 lundi 22 mars 2010
  • 31. Optional parens & semis ! Make statements and expressions look more like natural languages move(left); move left 27 lundi 22 mars 2010
  • 32. Named arguments ! In Groovy you can mix named and unnamed arguments for method parameters • named params are actually put in a map parameter • plus optional parens & semis take 1.pill, of: Chloroquinine, after: 6.hours ! Corresponds to a method signature like: def t ake(Map m, MedicineQuantity mq) 28 lundi 22 mars 2010
  • 33. BigDecimal by default ! Main reason why financial institutions often decide to use Groovy for their business rules! • Although these days rounding issues are overrated! ! Java vs Groovy for a simple interpolation equation BigDecimal uMinusv = c.subtract(a); BigDecimal vMinusl = b.subtract(c); BigDecimal uMinusl = a.subtract(b); return e.multiply(uMinusv) .add(d.multiply(vMinusl)) _HALF_UP); .divide(uMinusl, 10, BigDecimal.ROUND (d * (b - c) + e * (c - a)) / (a - b) 29 lundi 22 mars 2010
  • 34. Custom control structures, thanks to closures ! When closures are last, they can be put “out” of the parentheses surrounding parameters unless (a ccount.balance > 100.euros, { account.debit 100.euros }) unless (a ccount.balance > 100.euros) { account.debit 100.euros } ! Signature de f unless(boolean b, Closure c) 30 lundi 22 mars 2010
  • 35. Operator overloading a + b a.plus(b) • Currency amounts a - b a.minus(b) 15.euros + 10.dollars a * b a.multiply(b) a / b a.divide(b) • Distance handling a % b a.modulo(b) a ** b a.power(b) 10.kilometers - 10.meters 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 -a a.unaryMinus() account += 10.dollars ~a a.bitwiseNegate() account.credit 10.dollars 31 lundi 22 mars 2010
  • 36. The MOP (Meta-Object Protocol) lundi 22 mars 2010
  • 37. Groovy’s MOP ! All the accesses to methods, properties, constructors, operators, etc. can be intercepted thanks to the MOP ! While Java’s behavior is hard-wired at compile-time in the class ! Groovy’s runtime behavior is adaptable at runtime through the metaclass ! Different hooks for changing the runtime behavior • GroovyObject, custom MetaClass implementation, categories, ExpandoMetaClass 33 lundi 22 mars 2010
  • 38. GroovyObject ! All instances of classes created in Groovy implement the GroovyObject interface: get/setProperty(String name) invokeMeth od(String name, Object[] params) propertyMissing(String name) methodMissing( String name, Object[] params) get/setMetaClass(MetaClass mc) ! A GO can have “pretended” methods and properties 34 lundi 22 mars 2010
  • 39. MetaClass ! The core of Groovy’s MOP system invokeConstructor() invokeMe thod() and invokeStaticMethod() invokeMissingMethod() getProperty() and setProperty() ge tAttribute() and setAttribute() respondsTo() and hasProperty() ! MetaClasses can change the behavior of existing third-party classes — even from the JDK 35 lundi 22 mars 2010
  • 40. ExpandoMetaClass ! A DSL for MetaClasses! MoneyAmount.meta Class.constructor = { ... } Numb er.metaClass.getDollars = { ... } Di stance.metaClass.toMeters = { ... } Distance .metaClass.static.create = { ... } ! To avoid repetition of Type.metaClass, you can pass a closure to metaClass { ... } ! The delegate variable in closure represents the current instance, and it the default parameter 36 lundi 22 mars 2010
  • 42. A builder for HR softskills { ideas { capture 2 formulate 3 } ... } knowhow { languages { java 4 groovy 5 } ... } 38 lundi 22 mars 2010
  • 43. A builder for HR softskills { ideas { capture 2 formulate 3 } ... } knowhow { languages { java 4 groovy 5 } ... } 38 lundi 22 mars 2010
  • 44. Builders ! Builders are... • a mechanism for creating any tree-structered graph • the realization of the GoF builder pattern at the syntax level in Groovy • simply a clever use of chained method invocation, closures, parentheses omission, and use of the GroovyObject methods ! Existing builders • XML, Object graph, Swing, Ant, JMX, and more... 39 lundi 22 mars 2010
  • 45. The clever trick ! GroovyObject#invokeMethod() is used to catch all non-existing method calls in the context of the builder ! The nesting of closures visually shows the level of nesting / depth in the tree ! builder.m1(attr1:1, attr2:2, { builder.m2(..., {...}) } becomes equivalent to builder.m1(attr1:1, attr2:2) { m2(...) {...} } thanks to parens omission 40 lundi 22 mars 2010
  • 46. Adding properties to numbers ! Three possible approaches • create a Category • a category is a kind of decorator for default MCs • create a custom MetaClass • a full-blown MC class to implement and to set on the POGO instance • use ExpandoMetaClass • friendlier DSL approach but with a catch 41 lundi 22 mars 2010
  • 47. With a Category class DistanceCategory { static Di stance getMeters(Integer self) { new Distance(self, Unit.METERS) } } use(DistanceCategory) { 100.meters } ! Interesting scope: thread-bound & lexical ! Have to surround with “use” • but there are ways to hide it 42 lundi 22 mars 2010
  • 48. With an ExpandoMetaClass Number.metaClass.getMeters = {-> new Distance(delegate, Unit.METERS) } 100.meters ! Works for the class hierarchy for POJOs, and a flag exists to make it work for POGOs too ! But the catch is it’s really a global change, so beware EMC enhancements collisions 43 lundi 22 mars 2010
  • 49. Compile-time Metaprogramming ! Groovy 1.6 introduced AST Transformations ! Compile-time == No runtime performance penalty! Transformation 44 lundi 22 mars 2010
  • 50. Compile-time metaprogramming ! With metaprogramming, Groovy’s able to modify the behaviour of programs... at runtime ! Groovy 1.6 introduced AST Transformations • AST: Abstract Syntax Tree • Ability to change what’s being compiled at compile-time! • No runtime impact! • Lets you change the semantics of your programs! • Nice way of implementing patterns and removing boiler-plate technical code ! Two kinds of transformations: global and local 45 lundi 22 mars 2010
  • 51. AST Transformations ! Two kinds of transformations • Global transformations • applicable to all compilation units • Local transformations • applicable to marked program elements • using specific marker annotations 46 lundi 22 mars 2010
  • 52. AST Transformations in Groovy 1.6 ! Several (local) transformations finds their way • @Singleton — okay, not really a pattern :-) • @Immutable, @Lazy, @Delegate •@Newify • @Category and @Mixin •@PackageScope • Swing’s @Bindable and @Vetoable • Grape’s @Grab ! Let’s have a look at some of them 47 lundi 22 mars 2010
  • 53. The @Singleton anti-pattern !The evil Java singleton public class Evil { ; public st atic final Evil instance = new Evil() privavte Evil() {} ; } Evil getInstance() { return instance } !In Groovy now: @Singleton class Evil {} !A lazy version also: @Singleton(lazy = true) class Evil {} 48 lundi 22 mars 2010
  • 54. @Immutable ! To properly implement immutable classes • No mutators (state musn’t change) • Private final fields • Defensive copying of mutable components • Proper equals() / hashCode() / toString() for comparisons, or for keys in maps, etc. @Immutable class Coordinates { Double lat, lng } def c1 = new Coordinates(lat: 48.8, lng: 2.5) def c2 = new Coordinates(48.8, 2.5) assert c1 == c2 49 lundi 22 mars 2010
  • 55. @Lazy, not just for lazy dudes! ! When you need to lazily evaluate or instantiate complex data structures for class fields, mark them with the @Lazy annotation class Dude { @Lazy pets = retrieveFromSlowDB() } ! Groovy will handle the boiler-plate code for you! 50 lundi 22 mars 2010
  • 56. @Delegate Not just for managers! !You can delegate to fields of your class •Think multiple inheritance class Employee { def doTheWork() { "done" } } class Manager { ee() @Delegate Employee slave = new Employ } def god = new Manager() assert god.doTheWork() == "done" !Damn manager will get all the praise... 51 lundi 22 mars 2010
  • 57. Global transformations ! Implement ASTTransformation ! Annotate the transfo specifying a compilation phase ERSION) @GroovyASTTr ansformation(phase=CompilePhase.CONV public class MyTransformation implements ASTTransformation { Unit unit) publ ic void visit(ASTNode[] nodes, Source { ... } } ! For discovery, create the file META-INF/services/ org.codehaus.groovy.transform.ASTTransformation ! Add the fully qualified name of the class in that file 52 lundi 22 mars 2010
  • 58. Local transformations ! Same approach as Globale transformations ! But you don’t need the META-INF file ! Instead create an annotation to specify on which element the transformation should apply @Ret ention(RetentionPolicy.SOURCE) @Target([ElementType.METHOD]) @GroovyASTTransformationClass( ["fqn.MyTransformation"]) publ ic @interface WithLogging {...} 53 lundi 22 mars 2010
  • 59. Example: the Spock framework ! Changing the semantics of the original code ! But keeping a valid Groovy syntax @Speck class HelloSpock { () { def "can you figure out what I'm up to?" expect: name.size() == size where: name << ["Kirk", "Spock", "Scotty"] size << [4, 5, 6] } } ! Check out http://www.spockframework.org 54 lundi 22 mars 2010
  • 60. Various integration mechanisms ! Java 6’s javax.script.* APIs (aka JSR-223) ! Spring’s language namespace ! Groovy’s own mechanisms ! But a key idea is to externalize those DSL programs • DSL programs can have their own lifecycle • no need to redeploy an application because of a rule change • business people won’t see the technical code 55 lundi 22 mars 2010
  • 61. Java 6’s javax.script.* API ! Groovy 1.6 provides its own implementation of the javax.script.* API ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName(“Groovy”); String result = (String)engine.eval(“2+3”); 56 lundi 22 mars 2010
  • 62. Spring’s lang namespace ! POGOs (Plain Old Groovy Objects) can be pre-compiled as any POJO and used interchangeably with POJOs in a Spring application ! But Groovy scripts & classes can be loaded at runtime through the <lang:groovy/> namespace and tag ! Reloadable on change ! Customizable through a custom MetaClass <lang:groovy id="events" ovy" script-s ource="classpath:dsl/eventsChart.gro customizer-ref="eventsMetaClass" /> 57 lundi 22 mars 2010
  • 63. Groovy’s own mechanisms ! Eval • for evaluating simple expressions ! GroovyShell • for more complex scripts and DSLs ! GroovyClassLoader • the most powerful mechanism 58 lundi 22 mars 2010
  • 64. Eval ! Simple mechanism to evaluate math-like formulas Eval.me ( ‘3*4’) Eval.x (1, ‘3*x + 4’) Eval.xy (1, 2, ‘x + y’) Eval.xyz(1, 2, 3, ‘x * y - z’) 59 lundi 22 mars 2010
  • 65. GroovyShell ! A Binding provides a context of execution • can implement lazy evaluation if needed ! A base script class can be specified def binding = new Binding() binding.mass = 22.3 binding.velocity = 10.6 def shell = new GroovyShell(binding) shell. evaluate(“mass * velocity ** 2 / 2”) 60 lundi 22 mars 2010
  • 66. GroovyClassLoader ! Most powerful mechanism • could also visit or change the AST • scripts & classes can be loaded from elsewhere • more control on compilation GroovyClassLoader gcl = new GroovyClassLoader(); Class clazz = gcl.parseClass( new File(“f.groovy”)); GroovyObject instance = (GroovyObject)clazz.newInstance(); instance.setMetaClass(customMC); 61 lundi 22 mars 2010
  • 67. Externalize business rules ! Although Groovy DSLs can be embedded in normal Groovy classes, you should externalize them ! Store them elsewhere • in a database, an XML file, etc. ! Benefits • Business rules are not entangled in technical application code • Business rules can have their own lifecycle, without requiring application redeployments 62 lundi 22 mars 2010
  • 68. A few considerations 63 lundi 22 mars 2010
  • 69. Start small, with key concepts Beware over-engineering! lundi 22 mars 2010
  • 70. Grow your language progressively lundi 22 mars 2010
  • 71. Get your hands dirty Play with the end-users lundi 22 mars 2010
  • 72. Let your DSL fly, it’s not yours, it’s theirs! lundi 22 mars 2010
  • 73. Tight feedback loop Iterative process lundi 22 mars 2010
  • 74. Stay humble, You can’t get it right the 1st time. Don’t design alone at your desk Involve the end users from the start lundi 22 mars 2010
  • 75. Playing it safe in a sandbox lundi 22 mars 2010
  • 76. Various levels of sandboxing ! Groovy supports the usual Java Security Managers ! Use metaprogramming tricks to prevent calling / instanciating certain classes ! Create a special GroovyClassLoader AST code visitor to filter only the nodes of the AST you want to keep • ArithmeticShell in Groovy’s samples 71 lundi 22 mars 2010
  • 77. Test, test, test! ! Don’t just test for nominal cases • Explicitely test for errors! ! Ensure end-users get meaninful error messages 72 lundi 22 mars 2010
  • 78. Question & Answers 73 lundi 22 mars 2010
  • 79. Picture credits http://www.flickr.com/photos/featheredtar/2305070061/ http://commons.wikimedia.org/wiki/File:Platypus.jpg http://www.thedailygreen.com/cm/thedailygreen/images/WT/christmas- http://www.flickr.com/photos/joaomoura/2317171808/sizes/l/ tree-with-gifts-flipbook.jpg http://www.flickr.com/photos/wiccked/132687067/ http://www.flickr.com/photos/chicoer2001/188468490/ http://www.flickr.com/photos/timsamoff/252370986/sizes/l/ http://www.flickr.com/photos/olibac/4054644737/ http://www.flickr.com/photos/29738009@N08/2975466425/sizes/l/ http://www.flickr.com/photos/epsos/3384297473/ http://www.flickr.com/photos/howie_berlin/180121635/sizes/o/ http://media.techeblog.com/images/clapboard.jpg (clap) http://www.flickr.com/photos/yogi/1281980605/sizes/l/ http://www.flickr.com/photos/diegocupolo/3614879332/ (flower power) http://www.flickr.com/photos/dorseygraphics/1336468896/sizes/l/ http://www.flickr.com/photos/oskay/237442629/sizes/m/ (danger) http://www.flickr.com/photos/xcbiker/386876546/sizes/l/ http://www.partybox.co.uk/data/partyimages/ http://www.flickr.com/photos/pietel/152403711/sizes/o/ 250x250/6ftcutoutaustinpowers.jpg (austin powers) http://www.flickr.com/photos/forezt/192554677/sizes/o/ http://www.flickr.com/photos/27663074@N07/3413698337/ (jeepers creepers) http://keremkosaner.files.wordpress.com/2008/04/softwaredevelopment.gif http://www.flickr.com/photos/wheatfields/420088151/sizes/l/ http://www.jouy.inra.fr http://www.flickr.com/photos/therefromhere/518053737/sizes/l/ http://www.flickr.com/photos/ejpphoto/408101818/sizes/o/ http://www.flickr.com/photos/romainguy/230416692/sizes/l/ http://www.flickr.com/photos/solaro/2127576608/sizes/l/ http://www.flickr.com/photos/addictive_picasso/2874279971/sizes/l/ http://www.flickr.com/photos/biggreymare/2846899405/sizes/l/ http://www.flickr.com/photos/huangjiahui/3127634297/sizes/l/ http://www.flickr.com/photos/wwworks/2222523978/ (earth) http://www.flickr.com/photos/25831000@N08/3064515804/sizes/o/ http://static-p3.fotolia.com/jpg/ 00/01/64/30/400_F_1643044_YrBQoPnt0SC5gHAueG0bhx20yCSL42.jpg (trafic light) http://www.flickr.com/photos/lanier67/3147696168/sizes/l/ http://aldaria02.a.l.pic.centerblog.net/lz2levrz.jpg (griffon) http://www.flickr.com/photos/ktb/4916063/sizes/o/ http://www.flickr.com/photos/geishaboy500/104137788/ (soap) http://www.flickr.com/photos/nathonline/918128338/sizes/l/ Matriochka http://lang.russe.free.fr/images/matriochka.jpg http://www.flickr.com/photos/kevinsteele/39300193/sizes/l/ http://commons.wikimedia.org/wiki/File:Brueghel-tower-of-babel.jpg 74 lundi 22 mars 2010