DSL’s With Groovy
Paul Bowler
Senior Consultant, OpenCredo
“Domain-Specific”
Languages?
Domain?
–noun
a field of action, thought,
influence, etc.
Domains, domains, domains...!
Domain Language?
• Narrow, specialised focus
• Contains syntax and grammar to interact
with the domain
• Few, if any, cont...
So, like these?
...or these?
yes, ... and no!
What then?
“...most DSL’s are merely a thin facade over a library or
framework.”
Martin Fowler,ThoughtWorks
OS
Platform
Fr...
What’s wrong with code?
Developer
Domain
Expert
Cognitive Gap
How do DSL’s help?
• Expressive - Well-designed abstractions
• Simple - Reduce cognitive overhead
• Focussed - Deliver cla...
What’s wrong with code?
Developer
Domain
Expert
Cognitive Gap
Close the Cognitive Gap
Developer
Domain
Expert
How?
• External DSL - Separate from the ‘main’ language
e.g. SQL, XML, JSON
• Internal DSL -Valid code in the ‘main’ langu...
Why Groovy?
Less noise
More sugar
How?
• Builders
• Categories
• Meta-Object Protocol (MOP)
• Abstract Syntax Tree (AST) Transformations
Builders
• Great for hierarchical structures, such as
trees, collections of collections, etc.
• Built in support for XML, ...
Using builders
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.team(nickname:'DreamTeam') {
member...
Builder Methods
class MyBuilder extends BuilderSupport {
	

 public void setParent(Object parent, Object child) {
	

 }
	
...
Categories
• Allow syntax extensions, e.g:
def nextWeek = today + 7.days
• Any public static method is a candidate to be a...
Category Example
import org.apache.commons.lang.StringUtils
class StringCategory {
static capitalize( String self ){
Strin...
MOP
• Every object inherits from
groovy.lang.GroovyObject which
contains MetaClass
• ExpandoMetaClass extensions and hooks...
• Less code and cleaner implementation than categories
• Uses closures and delegates
• Can add or update/overload existing...
MOP Example
import org.apache.commons.lang.StringUtils
String.metaClass.capitalize = {
StringUtils.capitalize(delegate)
}
...
Abstract Syntax Tree
• Compile-time Meta Programming allowing
developers to hook into the compilation process
• No runtime...
Compilation Phases
1. Initialization: source files are opened and environment
configured
2. Parsing: the grammar is used to ...
Popular Transformations
• Bindable andVetoable transformation
• Category and Mixin transformations
• Delegate transformati...
It all looks so complicated!
Case Study - Grint
‘Groovier Integration!’
Grint
• Groovy DSL for Integration Patterns
• Deployable as a Grails plugin
• Baked for our DSL course
• Already in produc...
A Groovier Approach to Integration
• Events cause messages
• EDA 
• See Event-driven IO to get an idea
• Node.js
• Akka
• ...
Thank you
Upcoming SlideShare
Loading in …5
×

DSL's with Groovy

1,462 views

Published on

DSL's with Groovy presentation (OpenCredo 2011)

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,462
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
28
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

DSL's with Groovy

  1. 1. DSL’s With Groovy Paul Bowler Senior Consultant, OpenCredo
  2. 2. “Domain-Specific” Languages?
  3. 3. Domain? –noun a field of action, thought, influence, etc.
  4. 4. Domains, domains, domains...!
  5. 5. Domain Language? • Narrow, specialised focus • Contains syntax and grammar to interact with the domain • Few, if any, control structures (not ‘Turing Complete’) • Communicates instructions and configuration
  6. 6. So, like these?
  7. 7. ...or these?
  8. 8. yes, ... and no!
  9. 9. What then? “...most DSL’s are merely a thin facade over a library or framework.” Martin Fowler,ThoughtWorks OS Platform Framework DSL
  10. 10. What’s wrong with code? Developer Domain Expert Cognitive Gap
  11. 11. How do DSL’s help? • Expressive - Well-designed abstractions • Simple - Reduce cognitive overhead • Focussed - Deliver clarity of intent • Inclusive - Empower the domain expert
  12. 12. What’s wrong with code? Developer Domain Expert Cognitive Gap
  13. 13. Close the Cognitive Gap Developer Domain Expert
  14. 14. How? • External DSL - Separate from the ‘main’ language e.g. SQL, XML, JSON • Internal DSL -Valid code in the ‘main’ language • Language Workbench - Specialised ‘IDE’ as editing environment with ‘human-centric’ graphical representation
  15. 15. Why Groovy? Less noise More sugar
  16. 16. How? • Builders • Categories • Meta-Object Protocol (MOP) • Abstract Syntax Tree (AST) Transformations
  17. 17. Builders • Great for hierarchical structures, such as trees, collections of collections, etc. • Built in support for XML, HTML, Swing, etc • Roll your own by extending ‘BuilderSupport’ class
  18. 18. Using builders def writer = new StringWriter() def xml = new MarkupBuilder(writer) xml.team(nickname:'DreamTeam') { member(name:'John Smith', age:'32') { nationality('British') job(type:'full-time', 'Java Developer') } member(name:'Sue Perb', age:'25') { nationality('Australian') job(type:'full-time', 'Tester') } member(name:'Fred Bloggs', age:'30') { nationality('Irish') job(type:'contract', 'Build Guru') } }
  19. 19. Builder Methods class MyBuilder extends BuilderSupport { public void setParent(Object parent, Object child) { } public createNode(Object name) { } public createNode(Object name, Object value) { } public createNode(Object name, Map attributes) { } public createNode(Object name, Map attributes, Object value) { } }
  20. 20. Categories • Allow syntax extensions, e.g: def nextWeek = today + 7.days • Any public static method is a candidate to be a category method • The type of the first parameter is the target type that may have the new methods ‘injected’ • No need to extend a particular class or implement an interface • Gotcha! Methods added to classes for limited time using ThreadLocal.Also requires wrapping with use() method.
  21. 21. Category Example import org.apache.commons.lang.StringUtils class StringCategory { static capitalize( String self ){ StringUtils.capitalize(self) } static normalize( String self ){ self.split("_").collect { word -> word.toLowerCase().capitalize() }.join("") } } use( StringCategory ) { assert "Groovy" == "groovy".capitalize() assert "CamelCase" == "CAMEL_CASE".normalize() } 
  22. 22. MOP • Every object inherits from groovy.lang.GroovyObject which contains MetaClass • ExpandoMetaClass extensions and hooks: invokeMethod(), getProperty(), methodMissing() and propertyMissing() • Used extensively in Grails - Dynamic Finders (e.g. book.findAllByAuthor)
  23. 23. • Less code and cleaner implementation than categories • Uses closures and delegates • Can add or update/overload existing methods • No need for Use() • Can overload static methods • Has longer lifespan than categories • Inheritance not enabled by default for performance reasons MOP vs Categories
  24. 24. MOP Example import org.apache.commons.lang.StringUtils String.metaClass.capitalize = { StringUtils.capitalize(delegate) } String.metaClass.normalize = { delegate.split("_").collect { word -> word.toLowerCase().capitalize() }.join("") } assert "Groovy" == "groovy".capitalize() assert "CamelCase" == "CAMEL_CASE".normalize()
  25. 25. Abstract Syntax Tree • Compile-time Meta Programming allowing developers to hook into the compilation process • No runtime performance penalty • Global transformations using service locator file • Local transformations using annotations • Built using... builders! • Transformations must be performed in one of the nine defined compiler phases
  26. 26. Compilation Phases 1. Initialization: source files are opened and environment configured 2. Parsing: the grammar is used to to produce tree of tokens representing the source code 3. Conversion:An abstract syntax tree (AST) is created from token trees. 4. Semantic Analysis: Performs consistency and validity checks that the grammar can't check for, and resolves classes. 5. Canonicalization: Complete building the AST 6. Instruction Selection: instruction set is chosen, for example java5 or pre java5 7. Class Generation: creates the binary output in memory 8. Output: write the binary output to the file system 9. Finalisation: Perform any last cleanup
  27. 27. Popular Transformations • Bindable andVetoable transformation • Category and Mixin transformations • Delegate transformation • Immutable transformation • Lazy transformation • Newify transformation • PackageScope transformation • Singleton transformation
  28. 28. It all looks so complicated!
  29. 29. Case Study - Grint ‘Groovier Integration!’
  30. 30. Grint • Groovy DSL for Integration Patterns • Deployable as a Grails plugin • Baked for our DSL course • Already in production...
  31. 31. A Groovier Approach to Integration • Events cause messages • EDA  • See Event-driven IO to get an idea • Node.js • Akka • Even Spring Integration...
  32. 32. Thank you

×