ThoughtWorks



Language-Oriented Programming
and Language Workbenches:
Building Domain Languages
Atop Java™ Technology
Ne...
What This Session Covers
• Motivation
• Internal vs. external DSLs
• Building internal DSLs in
  • Java technology
  • Gro...
Questions
• Why is there so much XML mixed in with my
  Java code?
• Why do we need things like aspects?
• Why won’t every...
Modeling the World With Trees




              2007 JavaOneSM Conference | Session TS-1589 |   4
Modeling the Real World




              2007 JavaOneSM Conference | Session TS-1589 |   5
Changing Abstraction Styles
• Layers of abstraction using language
   • Not trees
• Trees and hierarchies still exist
   •...
Why Use DSLs for Abstraction?
• “Iced decaf triple grande vanilla skim with
   whip latte”
• “Scattered, smothered, covere...
Including Your Business
• Even if you are a Java technology ace
  • You still have to learn the DSL for your
    business ...
Observation
Every non-trivial human behavior has a
domain specific language.




                    2007 JavaOneSM Confer...
Nomenclature
• Coined by Martin Fowler
• Domain-specific language
  • A limited form of computer language designed for
   ...
DSLs vs. APIs
• An API has an explicit context

Coffee latte = new Coffee(Size.VENTI);
latte.setFatContent(FatContent.NON_...
DSLs vs. APIs
• DSLs have an implicit context
• Consider the real-world examples
  • The context is never mentioned
  • On...
Internal vs. External DSLs
• Internal DSLs sit atop your base language
  • Must follow the syntax rules of the base langua...
Fluent Interface
• Creating a readable model
   • Convert APIs to English-like sentences
• Slightly harder to write
• Much...
Car API
Car car = new CarImpl();
MarketingDescription desc = new
  MarketingDescriptionImpl();
desc.setType(quot;Boxquot;)...
Car Fluent Interface
Car car = new CarImpl().withMarketingDescriptionOf(
   new MarketingDescriptionImpl(quot;Boxquot;, qu...
Existing Fluent Interfaces




              2007 JavaOneSM Conference | Session TS-1589 |   17
Fluent Interface: Hamcrest
• Hamcrest is an open source library from Google
  that creates fluent interfaces around JUnit
...
Fluent Interface: Mocks
• JMock
 class PublisherTest extends MockObjectTestCase {
     public void testOneSubscriberReceiv...
Building Internal DSLs
In Java Technology




                     2007 JavaOneSM Conference | Session TS-1589 |   20
Example: Logging Configuration
• Logger setup is ugly
• Very API-ish
• Uses
  • A properties file
  • Code
  • An XML file...
Fluent Interface: Wrapping iBatis
• Humane interfaces improve the readability
  of any code
• You can wrap existing APIs i...
Java Technology: A Calendar DSL
• Goal
  • Create a calendar application in Java technology
    using DSL techniques
  • P...
Building Internal DSLs
In Groovy




              2007 JavaOneSM Conference | Session TS-1589 |   24
Internal DSLs in Groovy
• Groovy makes a better base for DSLs
  •   Open classes via categories
  •   Closures
  •   Loose...
Building Blocks: Closures
• Closures mimic scope capturing
  method pointers
• Like a method, a closure defines a scope
  ...
Building Blocks: Open Classes
• Open Classes via categories
• Groovy allows you to attach methods to an
  existing class
 ...
Time DSL in Groovy
• The goal: create a fluent interface around time
  spans and calendars
• Target syntax
 2.days.fromTod...
Who Returns What?
    2.days.fromToday.at(4.pm)

• 4.pm = Integer
• At
     • Accepts Integer
     • = Calendar
•     from...
Builders in Groovy
• Builders make it much easier to build
  structures
   • XML documents
   • Swing user interfaces
• Bu...
Groovy: Calendar
• The goal
  • Create an appointment calendar using DSLs
  • Demonstrates
     • Open classes
     • Clos...
Building Internal DSLs
In Ruby




              2007 JavaOneSM Conference | Session TS-1589 |   32
Ruby
• Ruby allows you to take DSL writing
  much further
• Ruby features that enable DSLs
  • True open classes
  • Closu...
Time DSL in Ruby
• Goal
  • Support time ranges in Ruby
• Demo
  • time_dsl.rb
  • time_dsl_test.rb




                  ...
Ruby Calendar
• Our calendar example in Ruby
• Demo
  • calendar_fluent.rb
• Functionally the same as the Groovy one
• Cle...
Building External DSLs




             2007 JavaOneSM Conference | Session TS-1589 |   36
Language Workbenches
• A language workbench is a tool that supports
  Language oriented programming
• Today’s language wor...
Compilation Cycle (Since CS-101)




              2007 JavaOneSM Conference | Session TS-1589 |   38
“Post-IntelliJ” IDEs
• First tool that allowed you to edit against
  the abstract syntax tree instead of text
• How refact...
Workbenches




              2007 JavaOneSM Conference | Session TS-1589 |   40
Language Workbenches
• Editable representation is a projection of the
  abstract representation
• Abstract representation ...
JetBrains MPS




                2007 JavaOneSM Conference | Session TS-1589 |   42
DSL Best Practices




             2007 JavaOneSM Conference | Session TS-1589 |   43
Start with the End
• When using a flexible base language,
  envision the perfect result
• The Rake napkin




            ...
Test, Test, Test!
• Writing the DSL is the tricky part
   • Using it should be easy
   • Otherwise you’ve made some mistak...
The Problem Domain
•   Keep it as cohesive as possible
•   Don’t try to write the entire universe in your DSL
•   Better o...
DSLs
• A huge competitive advantage
  • All your code is abstracted at the problem domain
  • Harder to write, easier to m...
Questions?
Samples and slides at www.nealford.com

Neal Ford
www.nealford.com
nford@thoughtworks.com
memeagora.blogspot.co...
Upcoming SlideShare
Loading in …5
×

Language-Oriented Programming and Language Workbenches: Building Domain Languages Atop Java Technology

1,775 views
1,718 views

Published on

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

No Downloads
Views
Total views
1,775
On SlideShare
0
From Embeds
0
Number of Embeds
72
Actions
Shares
0
Downloads
38
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Language-Oriented Programming and Language Workbenches: Building Domain Languages Atop Java Technology

  1. 1. ThoughtWorks Language-Oriented Programming and Language Workbenches: Building Domain Languages Atop Java™ Technology Neal Ford ThoughtWorker/Meme Wrangler ThoughtWorks www.thoughtworks.com Session TS-1589 2007 JavaOneSM Conference | Session TS-1589 |
  2. 2. What This Session Covers • Motivation • Internal vs. external DSLs • Building internal DSLs in • Java technology • Groovy • Ruby (via JRuby) • Building external DSLs • DSL best practices 2007 JavaOneSM Conference | Session TS-1589 | 2
  3. 3. Questions • Why is there so much XML mixed in with my Java code? • Why do we need things like aspects? • Why won’t everyone shut up already about Ruby on Rails? • Is there an evolutionary step beyond object- oriented programming? 2007 JavaOneSM Conference | Session TS-1589 | 3
  4. 4. Modeling the World With Trees 2007 JavaOneSM Conference | Session TS-1589 | 4
  5. 5. Modeling the Real World 2007 JavaOneSM Conference | Session TS-1589 | 5
  6. 6. Changing Abstraction Styles • Layers of abstraction using language • Not trees • Trees and hierarchies still exist • Underneath a stronger abstraction layer • Objects, aspects, generics, et al become the building blocks for DSLs • Allows developers to work at a higher level of abstraction • Declarative vs. imperative programming 2007 JavaOneSM Conference | Session TS-1589 | 6
  7. 7. Why Use DSLs for Abstraction? • “Iced decaf triple grande vanilla skim with whip latte” • “Scattered, smothered, covered” • The Waffle House Hash Brown language has 8 keywords (all inflected verbs) • Scattered, smothered, covered, chunked, topped, diced, peppered, and capped • “Route 66, swinging, easy on the chorus, extra solo at the coda, and bump at the end” • “OMFG D00d Bob is t3h UBER 1337 R0XX0RZ LOL” 2007 JavaOneSM Conference | Session TS-1589 | 7
  8. 8. Including Your Business • Even if you are a Java technology ace • You still have to learn the DSL for your business on day 1 • This is the hardest part of your job 2007 JavaOneSM Conference | Session TS-1589 | 8
  9. 9. Observation Every non-trivial human behavior has a domain specific language. 2007 JavaOneSM Conference | Session TS-1589 | 9
  10. 10. Nomenclature • Coined by Martin Fowler • Domain-specific language • A limited form of computer language designed for a specific class of problems • Language-oriented programming • The general style of development which operates about the idea of building software around a set of domain specific languages 2007 JavaOneSM Conference | Session TS-1589 | 10
  11. 11. DSLs vs. APIs • An API has an explicit context Coffee latte = new Coffee(Size.VENTI); latte.setFatContent(FatContent.NON_FAT); latte.setWhip(Whip.NONE); latte.setFoam(Foam.NONE); latte.setTemperature(Temp.EXTRA_HOT); latte.setStrength(5); 2007 JavaOneSM Conference | Session TS-1589 | 11
  12. 12. DSLs vs. APIs • DSLs have an implicit context • Consider the real-world examples • The context is never mentioned • Once a context is established, repeating it over and over is just noise Venti half-caf, non-fat, extra hot, no foam, no whip latte 2007 JavaOneSM Conference | Session TS-1589 | 12
  13. 13. Internal vs. External DSLs • Internal DSLs sit atop your base language • Must follow the syntax rules of the base language • Why Groovy and Ruby make better bases • External DSLs • Create a lexer and parser • Can take on any syntax you like • Let your imagination be your guide! • Hard to create… 2007 JavaOneSM Conference | Session TS-1589 | 13
  14. 14. Fluent Interface • Creating a readable model • Convert APIs to English-like sentences • Slightly harder to write • Much easier to read 2007 JavaOneSM Conference | Session TS-1589 | 14
  15. 15. Car API Car car = new CarImpl(); MarketingDescription desc = new MarketingDescriptionImpl(); desc.setType(quot;Boxquot;); desc.setSubType(quot;Insulatedquot;); desc.setAttribute(quot;lengthquot;, quot;50.5quot;); desc.setAttribute(quot;ladderquot;, quot;yesquot;); desc.setAttribute(quot;lining typequot;, quot;corkquot;); car.setDescription(desc); 2007 JavaOneSM Conference | Session TS-1589 | 15
  16. 16. Car Fluent Interface Car car = new CarImpl().withMarketingDescriptionOf( new MarketingDescriptionImpl(quot;Boxquot;, quot;Insulated”). andAttributeOf(quot;lengthquot;, quot;50.5quot;). andIncludesA(quot;ladderquot;). andAttributeOf(quot;lining typequot;, quot;corkquot;)); 2007 JavaOneSM Conference | Session TS-1589 | 16
  17. 17. Existing Fluent Interfaces 2007 JavaOneSM Conference | Session TS-1589 | 17
  18. 18. Fluent Interface: Hamcrest • Hamcrest is an open source library from Google that creates fluent interfaces around JUnit matchers assertThat(theBiscuit, equalTo(myBiscuit)); assertThat(theBiscuit, is(equalTo(myBiscuit))); assertThat(theBiscuit, is(myBiscuit)); 2007 JavaOneSM Conference | Session TS-1589 | 18
  19. 19. Fluent Interface: Mocks • JMock class PublisherTest extends MockObjectTestCase { public void testOneSubscriberReceivesAMessage() { Mock mockSubscriber = mock(Subscriber.class); Publisher publisher = new Publisher(); publisher.add((Subscriber) mockSubscriber.proxy()); final String message = quot;messagequot;; // expectations mockSubscriber.expects(once()). method(quot;receivequot;).with(eq(message)); // execute publisher.publish(message); } } 2007 JavaOneSM Conference | Session TS-1589 | 19
  20. 20. Building Internal DSLs In Java Technology 2007 JavaOneSM Conference | Session TS-1589 | 20
  21. 21. Example: Logging Configuration • Logger setup is ugly • Very API-ish • Uses • A properties file • Code • An XML file • Demo • LoggingConfiguration.java 2007 JavaOneSM Conference | Session TS-1589 | 21
  22. 22. Fluent Interface: Wrapping iBatis • Humane interfaces improve the readability of any code • You can wrap existing APIs in fluent interfaces • Example • iBatis is an open source O/R mapping tool • It drips of API style of coding • Wrapping iBatis access in a fluent interface • Demo • EventPersisterImpl.java 2007 JavaOneSM Conference | Session TS-1589 | 22
  23. 23. Java Technology: A Calendar DSL • Goal • Create a calendar application in Java technology using DSL techniques • Primarily uses fluent interface • Demo • Appointment.java • AppointmentCalendar.java • CalendarDemo.java 2007 JavaOneSM Conference | Session TS-1589 | 23
  24. 24. Building Internal DSLs In Groovy 2007 JavaOneSM Conference | Session TS-1589 | 24
  25. 25. Internal DSLs in Groovy • Groovy makes a better base for DSLs • Open classes via categories • Closures • Looser syntax rules • Dynamic typing 2007 JavaOneSM Conference | Session TS-1589 | 25
  26. 26. Building Blocks: Closures • Closures mimic scope capturing method pointers • Like a method, a closure defines a scope • Can still reference variables from the enclosing scope • Accepts parameters • Allows “with” semantics with categories • In a DSL, provides containership semantics 2007 JavaOneSM Conference | Session TS-1589 | 26
  27. 27. Building Blocks: Open Classes • Open Classes via categories • Groovy allows you to attach methods to an existing class • Either Groovy or Java Development Kit (JDK™) • Yes, you can add methods to String • Categories are classes with static methods • Each method’s first parameter is self • Fake object-orientation • Category demo = Adding methods to String 2007 JavaOneSM Conference | Session TS-1589 | 27
  28. 28. Time DSL in Groovy • The goal: create a fluent interface around time spans and calendars • Target syntax 2.days.fromToday.at(4.pm) • Returns a calendar for that date and time • Demo • IntegerWithTimeSupport.groovy • CalendarDsl.groovy • TestTime.groovy • CalendarDslDemo.groovy 2007 JavaOneSM Conference | Session TS-1589 | 28
  29. 29. Who Returns What? 2.days.fromToday.at(4.pm) • 4.pm = Integer • At • Accepts Integer • = Calendar • fromToday = Calendar • Days = Integer • 2 = Integer 2007 JavaOneSM Conference | Session TS-1589 | 29
  30. 30. Builders in Groovy • Builders make it much easier to build structures • XML documents • Swing user interfaces • Built using a fluent interface • Demo • Generating XML schema and POJO from a database schema 2007 JavaOneSM Conference | Session TS-1589 | 30
  31. 31. Groovy: Calendar • The goal • Create an appointment calendar using DSLs • Demonstrates • Open classes • Closures • Loose syntax rules • Demo • Appointment.groovy • AppointmentCalendar.groovy • IntegerWithTimeSupport.groovy • AppointmentCalendarDemo.groovy 2007 JavaOneSM Conference | Session TS-1589 | 31
  32. 32. Building Internal DSLs In Ruby 2007 JavaOneSM Conference | Session TS-1589 | 32
  33. 33. Ruby • Ruby allows you to take DSL writing much further • Ruby features that enable DSLs • True open classes • Closures • Really flexible syntax rules 2007 JavaOneSM Conference | Session TS-1589 | 33
  34. 34. Time DSL in Ruby • Goal • Support time ranges in Ruby • Demo • time_dsl.rb • time_dsl_test.rb 2007 JavaOneSM Conference | Session TS-1589 | 34
  35. 35. Ruby Calendar • Our calendar example in Ruby • Demo • calendar_fluent.rb • Functionally the same as the Groovy one • Cleaner syntax • Less cruft • True open classes 2007 JavaOneSM Conference | Session TS-1589 | 35
  36. 36. Building External DSLs 2007 JavaOneSM Conference | Session TS-1589 | 36
  37. 37. Language Workbenches • A language workbench is a tool that supports Language oriented programming • Today’s language workbenches • Intentional Software (developed by Simonyi) • Software factories (developed by Microsoft) • Meta Programming System (developed by JetBrains) 2007 JavaOneSM Conference | Session TS-1589 | 37
  38. 38. Compilation Cycle (Since CS-101) 2007 JavaOneSM Conference | Session TS-1589 | 38
  39. 39. “Post-IntelliJ” IDEs • First tool that allowed you to edit against the abstract syntax tree instead of text • How refactoring and other intelligent support works 2007 JavaOneSM Conference | Session TS-1589 | 39
  40. 40. Workbenches 2007 JavaOneSM Conference | Session TS-1589 | 40
  41. 41. Language Workbenches • Editable representation is a projection of the abstract representation • Abstract representation has to be comfortable with errors and ambiguities 2007 JavaOneSM Conference | Session TS-1589 | 41
  42. 42. JetBrains MPS 2007 JavaOneSM Conference | Session TS-1589 | 42
  43. 43. DSL Best Practices 2007 JavaOneSM Conference | Session TS-1589 | 43
  44. 44. Start with the End • When using a flexible base language, envision the perfect result • The Rake napkin 2007 JavaOneSM Conference | Session TS-1589 | 44
  45. 45. Test, Test, Test! • Writing the DSL is the tricky part • Using it should be easy • Otherwise you’ve made some mistakes • Test all the small parts 2007 JavaOneSM Conference | Session TS-1589 | 45
  46. 46. The Problem Domain • Keep it as cohesive as possible • Don’t try to write the entire universe in your DSL • Better off using a bunch of very specific DSLs • JetBrains and the way they are using MPS 2007 JavaOneSM Conference | Session TS-1589 | 46
  47. 47. DSLs • A huge competitive advantage • All your code is abstracted at the problem domain • Harder to write, easier to maintain • Show your code to your business analysts for verification 2007 JavaOneSM Conference | Session TS-1589 | 47
  48. 48. Questions? Samples and slides at www.nealford.com Neal Ford www.nealford.com nford@thoughtworks.com memeagora.blogspot.com This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License: http://creativecommons.org/licenses/by-sa/2.5/ 2007 JavaOneSM Conference | Session TS-1589 |

×