Groovy DSL roundup

Posted by Warner Onstine on April 24, 2008

This is my first attempt at categorizing some of the DSLs I’ve run across into some kind of logical grouping. First I’ll list out some Groovy DSL examples (sound off in the comments for those I’m not aware of, the more the better). I’ll go through the DSLs first and then look at the possible categories after the break. And the first two are mine that I created

I know there are more out there but this is a good starting point for sure.

Now, on to the actual categories of DSL “types”

I have been paying attention to Martin Fowler’s new DSL book in which he specifies several types of Internal DSLs. I’m not 100% on board with all of these yet, but here they are (of course these may change as this is a work in progress, so if he changes them it isn’t my fault :P ):

  • Expression Builder: A layer that provides a fluent interface over a regular API
  • Function Sequence: A combination of function calls as a sequence of statements.
  • Nested Function: Compose functions by nesting function calls as arguments of of other calls.
  • Method Chaining: Make modifier methods return the host object so that multiple modifiers can be invoked in a single expression.
  • Object Scoping: Put DSL code in a subclass of a class that provdes the DSL vocabulary.
  • Closure:
    • Nested Closure: Express statement sub-elements of a function call by putting them into a closure in an argument.
  • Literal Collection Expression: Form language expressions using literal collection syntax
  • Dynamic Reception: Handle messages without defining them in the code
  • Annotation: Data about program elements, such as classes and methods, which can be processed during compilation or execution.
  • Macro: Define DSL expressions as macro definitions
  • Parse Tree Manipulation: Capture the parse tree of a code fragment to manipulate it with DSL processing code.

Ok, so these are the basic categories as Martin has defined them. How do these map up to the tools and techniques we have in Groovy?

  • Method/Property Missing – a special method that is called when a method can not be found allowing a developer to intercept the call
    • Maps to Dynamic Reception fairly well
  • Categories – allows new methods to be added to any class at runtime
    • Could fit into Object Scoping or maybe a new one, Duck Typing? – not sure
  • ExpandoMetaClass – a dynamically expandable bean
    • Again Dynamic Reception
  • Closures/Nested Closures
    • Closures/Nested Closures
  • Relaxed rules on the use of parentheses
    • Hmm, not sure where this would fit
  • Built-in list and map syntax
    • I believe this is Literal Collection Expression
  • Ability to dynamically add methods to an interface and have concrete classes also have the methods
    • Again, this sounds like Dynamic Reception
  • Operator overloading
    • Hmm, again I’m not sure where this fits
  • Annotations
    • Annotation

First up we have our builders (AntBuilder, XMLBuilder, Criteria Builder, etc.) these essentially mimic some other existing structure (an Ant build file, XML file, or SQL syntax). What patterns do these use? Just off the top of my head I think I see:

  • Expression Builder
  • Nested Closures
  • Dynamic Reception
  • Literal Collection Expression

JSON-lib’s Groovy interface has the following:

  • Literal Collection Expression
  • Dynamic Reception
  • Operator Overloading (as)

My Groovy Higher Order Messaging DSL has:

  • Dynamic Reception
  • Nested Closures

My Groovy Math DSL has:

  • Dynamic Reception
  • Nested Closures (or possibly what would be considered Function Sequence in some cases, even though they aren’t functions but it might fit)
  • Operator Overloading

GroovyLab has:

  • Expression Builder
  • Probably has more just don’t have time to dig into the code – I’m just looking at the quick examples)
  • Operator Overloading

Guillaume’s Unit Manipulation DSL has:

  • Expression Builder
  • Dynamic Reception
  • Closure/Nested Closure
  • Operator Overloading

Ken Barclay’s GParsec has:

  • Dynamic Reception
  • Parse Tree Manipulation? (not sure if this qualifies for this or not)

GroovyRestlet DSL has:

  • Literal Collection Expression
  • Closure/Nested Closure
  • Function Sequence

GSpec has:

  • Closure/Nested Closure
  • Function Sequence
  • Dynamic Reception

Grails’ Domain Class Validation DSL has:

  • Literal Colleciton Expression
  • Closure
  • Macros?

Tiago Antão’s Malaria Drug DSL has:

  • Object Scoping
  • Dynamic Reception

Human readable date modification has:

  • Object Scoping
  • Operator Overloading

Now, one of the big things that I think Fowler is missing here (and one that you can see several DSLs take advantage of) is Operator Overloading/Overriding. This, I think, is a key technique in DSLs and one that can make a DSL go from good to great. It’s all about letting the user think in the context they are in – be it math matrices, sql queries, file and string manipulation (overriding the << or >> operators). It’s all about the user’s context and making it easy for them to “think” in their domain and not have to worry about the language implementation (I use it quite heavily in my Math DSL to implement matrix operators for example).

I know I didn’t hit on all the DSLs I mentioned, but will try and come up with a wiki or something that people can contribute back to. In the mean time sound off in the comments if you have a DSL that I didn’t mention, or you feel my categorization is wrong (and why). I’m also curious if there are examples of some of the ones I didn’t touch on such as Annotations. This is an initial stab at this and as I said earlier I’m not 100% on board with how Fowler has organized things but I think it’s a good start.

Share and Enjoy:
  • Print
  • Digg
  • Reddit
  • del.icio.us
  • Twitter
  • Facebook
  • Google Bookmarks
  • DZone
Related Posts:
Trackbacks

Trackbacks are closed.

Comments

Comments are closed.


Easy AdSense by Unreal