Top Banner
DSL’s With Groovy Paul Bowler Senior Consultant, OpenCredo
32

DSL's with Groovy

Nov 07, 2014

Download

Technology

paulbowler

DSL's with Groovy presentation (OpenCredo 2011)
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: DSL's with Groovy

DSL’s With GroovyPaul Bowler

Senior Consultant, OpenCredo

Page 2: DSL's with Groovy

“Domain-Specific”Languages?

Page 3: DSL's with Groovy

Domain?

–nouna field of action, thought,

influence, etc.

Page 4: DSL's with Groovy

Domains, domains, domains...!

Page 5: DSL's with Groovy

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

Page 6: DSL's with Groovy

So, like these?

Page 7: DSL's with Groovy

...or these?

Page 8: DSL's with Groovy

yes, ... and no!

Page 9: DSL's with Groovy

What then?

“...most DSL’s are merely a thin facade over a library or framework.”

Martin Fowler, ThoughtWorks

OS

PlatformFramework

DSL

Page 10: DSL's with Groovy

What’s wrong with code?

DeveloperDomain Expert

Cognitive Gap

Page 11: DSL's with Groovy

How do DSL’s help?

• Expressive - Well-designed abstractions

• Simple - Reduce cognitive overhead

• Focussed - Deliver clarity of intent

• Inclusive - Empower the domain expert

Page 12: DSL's with Groovy

What’s wrong with code?

DeveloperDomain Expert

Cognitive Gap

Page 13: DSL's with Groovy

Close the Cognitive Gap

DeveloperDomain Expert

Page 14: DSL's with Groovy

How?

• External DSL - Separate from the ‘main’ languagee.g. SQL, XML, JSON

• Internal DSL - Valid code in the ‘main’ language

• Language Workbench - Specialised ‘IDE’ as editing environment with ‘human-centric’ graphical representation

Page 15: DSL's with Groovy

Why Groovy?

Less noise More sugar

Page 16: DSL's with Groovy

How?

• Builders

• Categories

• Meta-Object Protocol (MOP)

• Abstract Syntax Tree (AST) Transformations

Page 17: DSL's with Groovy

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

Page 18: DSL's with Groovy

Using buildersdef 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') }}

Page 19: DSL's with Groovy

Builder Methodsclass 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) { }}

Page 20: DSL's with Groovy

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.

Page 21: DSL's with Groovy

Category Exampleimport 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()} 

Page 22: DSL's with Groovy

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)

Page 23: DSL's with Groovy

• 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

Page 24: DSL's with Groovy

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()

Page 25: DSL's with Groovy

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

Page 26: DSL's with Groovy

Compilation Phases1. Initialization: source files are opened and environment

configured2. Parsing: the grammar is used to to produce tree of tokens

representing the source code3. 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 AST6. Instruction Selection: instruction set is chosen, for example java5

or pre java57. Class Generation: creates the binary output in memory8. Output: write the binary output to the file system9. Finalisation: Perform any last cleanup

Page 28: DSL's with Groovy

It all looks so complicated!

Page 29: DSL's with Groovy

Case Study - Grint‘Groovier Integration!’

Page 30: DSL's with Groovy

Grint

• Groovy DSL for Integration Patterns

• Deployable as a Grails plugin

• Baked for our DSL course

• Already in production...

Page 31: DSL's with Groovy

A Groovier Approach to Integration

• Events cause messages

• EDA 

• See Event-driven IO to get an idea

• Node.js

• Akka

• Even Spring Integration...

Page 32: DSL's with Groovy

Thank you