Smoothing Your Java with DSLs Dmit ry Jemerov Development Lead JetBrains, Inc. ht tp://www.jetbrains.com/
Learn about the multiple ways you can use domain-specific languages in your Java project to make your code more readable and maintainable
Agenda DSL Overview DSLs in Java DSLs in Scripting Languages JetBrains MPS
What is a DSL? Computer programming language Limited expressiveness Domain focus
DSL Classification External Regular Expressions SQL CSS
DSL Classification External XML-based Ant XSLT
DSL Classification External XML-based Internal Query integration: Squill Testing: JMock, EasyMock
DSL Classification External XML-based Internal Scripting Build: Gradle, Buildr Testing: easyb UI: Glimmer, Monkeybars
DSL Classification External XML-based Internal Scripting Language Workbench MPS “Oslo”
Why Use DSLs? Raising level of abstraction Separating the “what” from the “how” Separating stable and frequently changing parts of the system Enabling domain expert contributions
DSLs: Code or Data? Depends on where you look from TrueType fonts: actually code for a rather powerful VM
Integrating DSLs Interpretation Model is built by executing internal DSL or parsing external DSL Interpreter executes operations described by DSL Code Generation DSL drives generation of host language code DSL-generated code compiled with rest of app
Agenda DSL Overview DSLs in Java DSLs in Scripting Languages JetBrains MPS
Squill squill  .from(pets)  .where(eq(pets.species, “Cat”)) .orderBy(asc(pets.name)) .selectList(pets.name,  pets.birthDate)); https://squill.dev.java.net/
EasyMock expect(mock.voteForRemoval(“A")) .andReturn((byte) 42) .atLeastOnce(); http://www.easymock.org/
IntelliJ IDEA PSI Patterns
Regular vs Fluent API Regular: a method call executes an operation object.verbNoun(param1, …, paramN)   Fluent: a method call tells  one thing  about an operation that will be executed object.noun1(param1).noun2(param2)…
Fluent API Patterns Method chaining Builder objects Static factory methods Static imports Initializer blocks in anonymous classes
Method Chaining class C { C value1(Object v1) { this.value1 = v1; return this; } C value2(Object v2) { … } } c.value1(o1).value2(o2)
Builder Objects class CBuilder { CBuilder value1(Object v1) { … } CBuilder value2(Object v2) { … } C build() {  return new C(value1, value2); } }
Factory Methods, Static Imports class CFactory { static <T> C<T> newC() { return new C<T>(); }  } import static CFactory.*; C<String> c = newC();
Initializer Blocks (JMock) context.checking(new Expectations() {{   oneOf (subscriber).receive(message);  }});
Java Internal DSL Advantages Low entry barrier, no external dependencies Full IDE support (code completion etc.) Strong typing and compile-time error checking
Java Internal DSL Drawbacks Readability is not as good as with other solutions
Agenda DSL Overview DSLs in Java DSLs in Scripting Languages JetBrains MPS
easyb given &quot;a stack with one pushed value&quot;, {   stack = new Stack()    pushVal = &quot;foo&quot;   stack.push(pushVal)  }  when &quot;pop is called&quot;, {    popVal = stack.pop()  }  then &quot;that object should be returned&quot;, {   popVal.shouldBe pushVal  } http://easyb.org/
Glimmer shell { text &quot;Contact Manager“ composite { layout GridLayout.new(2, false) label { text &quot;First &Name: &quot;} text { text bind(presenter, :first_name) } } } http://rubyforge.org/projects/glimmer/
RubyMine Parameter Definitions define_params  'validates_presence_of' ,  migration_ref ,  [migration_ref ,  {    :message  =>   nil ,    :on  =>  one_of(:save ,  :create ,  :update) ,   :if  =>  method_ref( 'ActiveRecord::Base' ) }]
Scripting Language Advantages Closures Properties List/map literals Operator overloading Handling of missing methods
Integrating DSL Scripts Joint compilation Script statically compiled to bytecode Allows direct calls of script code from Java Dynamic invocation Script invoked via javax.scripting or language-specific embedding API Allows dynamic discovery of scripts Allows modifying scripts without app restart or recompilation
Agenda DSL Overview DSLs in Java DSLs in Scripting Languages JetBrains MPS
MPS History Started as a research project back in 2004 JetBrains issue tracker project being developed entirely in MPS Web framework Data access framework End-user functionality Released as open-source public beta in December 2008
Key Concepts of MPS Language  defines a set of  concepts  and relationships between them Models  are instances of a particular concept Editors  define how models of a particular concept are represented in the MPS IDE  Generators  define how models are translated into a different language
What MPS  doesn’t  have No text representation for code in a particular language No grammar for languages No way to import code in existing text-based language No dependency on specific output language generated Could be Java, JavaScript, CSS, XML…
Advanced MPS Reusing languages Business rules need formulas Can reuse MPS expression language: editor, generation etc. Extending languages Closures, ‘using’ blocks, complex numbers…
Summary You can use the fluent programming style in Java to make your code easier to read and less verbose DSLs built with scripting languages like Groovy and JRuby bring even further readability benefits JetBrains MPS is a whole new approach to DSLs
For More Information Martin Fowler’s DSL book:  http://martinfowler.com/dslwip/ JetBrains MPS:  http://www.jetbrains.com/mps/
Q&A Dmitry Jemerov [email_address]
Smoothing Your Java with DSLs Dmit ry Jemerov Development Lead JetBrains, Inc. ht tp://www.jetbrains.com/

Smoothing Your Java with DSLs

  • 1.
    Smoothing Your Javawith DSLs Dmit ry Jemerov Development Lead JetBrains, Inc. ht tp://www.jetbrains.com/
  • 2.
    Learn about themultiple ways you can use domain-specific languages in your Java project to make your code more readable and maintainable
  • 3.
    Agenda DSL OverviewDSLs in Java DSLs in Scripting Languages JetBrains MPS
  • 4.
    What is aDSL? Computer programming language Limited expressiveness Domain focus
  • 5.
    DSL Classification ExternalRegular Expressions SQL CSS
  • 6.
    DSL Classification ExternalXML-based Ant XSLT
  • 7.
    DSL Classification ExternalXML-based Internal Query integration: Squill Testing: JMock, EasyMock
  • 8.
    DSL Classification ExternalXML-based Internal Scripting Build: Gradle, Buildr Testing: easyb UI: Glimmer, Monkeybars
  • 9.
    DSL Classification ExternalXML-based Internal Scripting Language Workbench MPS “Oslo”
  • 10.
    Why Use DSLs?Raising level of abstraction Separating the “what” from the “how” Separating stable and frequently changing parts of the system Enabling domain expert contributions
  • 11.
    DSLs: Code orData? Depends on where you look from TrueType fonts: actually code for a rather powerful VM
  • 12.
    Integrating DSLs InterpretationModel is built by executing internal DSL or parsing external DSL Interpreter executes operations described by DSL Code Generation DSL drives generation of host language code DSL-generated code compiled with rest of app
  • 13.
    Agenda DSL OverviewDSLs in Java DSLs in Scripting Languages JetBrains MPS
  • 14.
    Squill squill .from(pets) .where(eq(pets.species, “Cat”)) .orderBy(asc(pets.name)) .selectList(pets.name, pets.birthDate)); https://squill.dev.java.net/
  • 15.
    EasyMock expect(mock.voteForRemoval(“A&quot;)) .andReturn((byte)42) .atLeastOnce(); http://www.easymock.org/
  • 16.
  • 17.
    Regular vs FluentAPI Regular: a method call executes an operation object.verbNoun(param1, …, paramN) Fluent: a method call tells one thing about an operation that will be executed object.noun1(param1).noun2(param2)…
  • 18.
    Fluent API PatternsMethod chaining Builder objects Static factory methods Static imports Initializer blocks in anonymous classes
  • 19.
    Method Chaining classC { C value1(Object v1) { this.value1 = v1; return this; } C value2(Object v2) { … } } c.value1(o1).value2(o2)
  • 20.
    Builder Objects classCBuilder { CBuilder value1(Object v1) { … } CBuilder value2(Object v2) { … } C build() { return new C(value1, value2); } }
  • 21.
    Factory Methods, StaticImports class CFactory { static <T> C<T> newC() { return new C<T>(); } } import static CFactory.*; C<String> c = newC();
  • 22.
    Initializer Blocks (JMock)context.checking(new Expectations() {{ oneOf (subscriber).receive(message); }});
  • 23.
    Java Internal DSLAdvantages Low entry barrier, no external dependencies Full IDE support (code completion etc.) Strong typing and compile-time error checking
  • 24.
    Java Internal DSLDrawbacks Readability is not as good as with other solutions
  • 25.
    Agenda DSL OverviewDSLs in Java DSLs in Scripting Languages JetBrains MPS
  • 26.
    easyb given &quot;astack with one pushed value&quot;, { stack = new Stack() pushVal = &quot;foo&quot; stack.push(pushVal) } when &quot;pop is called&quot;, { popVal = stack.pop() } then &quot;that object should be returned&quot;, { popVal.shouldBe pushVal } http://easyb.org/
  • 27.
    Glimmer shell {text &quot;Contact Manager“ composite { layout GridLayout.new(2, false) label { text &quot;First &Name: &quot;} text { text bind(presenter, :first_name) } } } http://rubyforge.org/projects/glimmer/
  • 28.
    RubyMine Parameter Definitionsdefine_params 'validates_presence_of' , migration_ref , [migration_ref , { :message => nil , :on => one_of(:save , :create , :update) , :if => method_ref( 'ActiveRecord::Base' ) }]
  • 29.
    Scripting Language AdvantagesClosures Properties List/map literals Operator overloading Handling of missing methods
  • 30.
    Integrating DSL ScriptsJoint compilation Script statically compiled to bytecode Allows direct calls of script code from Java Dynamic invocation Script invoked via javax.scripting or language-specific embedding API Allows dynamic discovery of scripts Allows modifying scripts without app restart or recompilation
  • 31.
    Agenda DSL OverviewDSLs in Java DSLs in Scripting Languages JetBrains MPS
  • 32.
    MPS History Startedas a research project back in 2004 JetBrains issue tracker project being developed entirely in MPS Web framework Data access framework End-user functionality Released as open-source public beta in December 2008
  • 33.
    Key Concepts ofMPS Language defines a set of concepts and relationships between them Models are instances of a particular concept Editors define how models of a particular concept are represented in the MPS IDE Generators define how models are translated into a different language
  • 34.
    What MPS doesn’t have No text representation for code in a particular language No grammar for languages No way to import code in existing text-based language No dependency on specific output language generated Could be Java, JavaScript, CSS, XML…
  • 35.
    Advanced MPS Reusinglanguages Business rules need formulas Can reuse MPS expression language: editor, generation etc. Extending languages Closures, ‘using’ blocks, complex numbers…
  • 36.
    Summary You canuse the fluent programming style in Java to make your code easier to read and less verbose DSLs built with scripting languages like Groovy and JRuby bring even further readability benefits JetBrains MPS is a whole new approach to DSLs
  • 37.
    For More InformationMartin Fowler’s DSL book: http://martinfowler.com/dslwip/ JetBrains MPS: http://www.jetbrains.com/mps/
  • 38.
    Q&A Dmitry Jemerov[email_address]
  • 39.
    Smoothing Your Javawith DSLs Dmit ry Jemerov Development Lead JetBrains, Inc. ht tp://www.jetbrains.com/