Top Banner
107

DSL Construction rith Ruby

Nov 01, 2014

Download

Technology

ThoughtWorks

Simplicity, ease of use, clean syntax and clear semantics are the characteristics of a good DSL that enable the users to focus on the problem. It is non-trivial to define, develop and maintain a DSL, especially using traditional compiler techniques. The Ruby programming language solves this issue to a certain extent.

Topics Covered

* Fundamentals of DSLs.
* Introduction of Ruby features for writing DSLs.
* Writing a DSL - The speakers' experience, with examples.
* Challenges and Issues.

Speaker Profiles:
Harshal Hayatnagarkar is a researcher at Tata Research Development and Design Centre, Pune (a division of TCS) with many years of experience in writing large-scale trading systems, DSLs and high performance machine learning systems. Currently he is writing a DSL for information visualization using Ruby.
Rohan Kini: is a Senior Developer at ThoughtWorks. He has been working with Ruby since 2005 on one of the earliest Ruby projects in India. He specializes in development of large-scale, web-based applications and scripting languages.
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 Construction rith Ruby
Page 2: DSL Construction rith Ruby

goals •  DSL Fundamentals •  Some Ruby Basics •  DSL construction with Ruby •  Advanced Topics - A step further •  Summary •  Q & A

Page 3: DSL Construction rith Ruby

problem?

Problem

Solution

reduce the gap

Customer

Programmer

Page 4: DSL Construction rith Ruby

01000001

Page 5: DSL Construction rith Ruby
Page 6: DSL Construction rith Ruby

evolution

expr

essi

ve

?

Object Oriented

Procedural

Assembly

100101010

Emergence of language

C

C++ Java

Problem

GA

P

Solution

Page 7: DSL Construction rith Ruby

•  Arm Ball •  Around the wicket •  Cow Corner •  Duck •  Fly Slip •  Googly

http://en.wikipedia.org/wiki/List_of_cricket_terms - an long list of cricket terms

the power of language

Page 8: DSL Construction rith Ruby

evolution

expr

essi

ve

DSL

Object Oriented

Procedural

Assembly

100101010

Emergence of language

C

C++ Java

Problem

GA

P

Solution

Page 9: DSL Construction rith Ruby

example

Monit – automatic management and monitoring - http://mmonit.com/

Page 10: DSL Construction rith Ruby

definition a computer programming language of limited

expressiveness focused on a particular domain

- Martin Fowler

Martin Fowlers book on DSLs - http://martinfowler.com/dslwip/

Page 11: DSL Construction rith Ruby

definition a computer programming language of

limited expressiveness focused on a particular domain

- Martin Fowler

Martin Fowlers book on DSLs - http://martinfowler.com/dslwip/

Page 12: DSL Construction rith Ruby

definition a computer programming language of

limited expressiveness focused on a particular domain

- Martin Fowler

Martin Fowlers book on DSLs - http://martinfowler.com/dslwip/

Page 13: DSL Construction rith Ruby

definition a computer programming language of

limited expressiveness focused on a particular domain

- Martin Fowler

Martin Fowlers book on DSLs - http://martinfowler.com/dslwip/

Page 14: DSL Construction rith Ruby

Domain Specific Languages vs.

General Purpose Languages

Page 15: DSL Construction rith Ruby

what DSLs bring to the table •  Quality •  Productivity •  Reliability •  Maintainability •  Reusability

Page 16: DSL Construction rith Ruby

what DSLs bring to the table •  Quality •  Productivity •  Reliability •  Maintainability •  Reusability

•  Social impact

Page 17: DSL Construction rith Ruby

what DSLs bring to the table •  Quality •  Productivity •  Reliability •  Maintainability •  Reusability

•  Social impact •  Validation at the domain level

Page 18: DSL Construction rith Ruby

no silver bullet!

Page 19: DSL Construction rith Ruby

no silver bullet! •  Learning curve

Page 20: DSL Construction rith Ruby

no silver bullet! •  Learning curve •  Good language design is hard

Page 21: DSL Construction rith Ruby

no silver bullet! •  Learning curve •  Good language design is hard •  Cost of building

Page 22: DSL Construction rith Ruby

no silver bullet! •  Learning curve •  Good language design is hard •  Cost of building •  Limited applicability

Page 23: DSL Construction rith Ruby

no silver bullet! •  Learning curve •  Good language design is hard •  Cost of building •  Limited applicability •  Maintenance

Page 24: DSL Construction rith Ruby

no silver bullet! •  Learning curve •  Good language design is hard •  Cost of building •  Limited applicability •  Maintenance •  Could be overused or abused

Page 25: DSL Construction rith Ruby

Types of DSL

Page 26: DSL Construction rith Ruby

external DSL

Need to build a parser to process the custom syntax

sql, make files, xml config files, regular expressions

Page 27: DSL Construction rith Ruby

advantages •  Free to use any syntax

Page 28: DSL Construction rith Ruby

advantages •  Free to use any syntax •  Run time evaluation

Page 29: DSL Construction rith Ruby

disadvantages •  Starts simple, can get ugly and complex

Page 30: DSL Construction rith Ruby

disadvantages •  Starts simple, can get ugly and complex •  Building parsers is difficult

Page 31: DSL Construction rith Ruby

disadvantages •  Starts simple, can get ugly and complex

•  Building parsers is difficult •  Lack of tooling support

Page 32: DSL Construction rith Ruby

internal DSL

Extends the host language

Page 33: DSL Construction rith Ruby

advantages •  Don't have to write and debug a new

language

Page 34: DSL Construction rith Ruby

advantages •  Don't have to write and debug a new

language

•  Full power of base language is available

Page 35: DSL Construction rith Ruby

advantages •  Don't have to write and debug a new

language

•  Full power of base language is available

•  Tooling support available

Page 36: DSL Construction rith Ruby

disadvantages •  constrained by the host language.

Page 37: DSL Construction rith Ruby

Ruby based DSLs are internal

Page 38: DSL Construction rith Ruby

DSLs - not special to Ruby

Page 39: DSL Construction rith Ruby

Ruby is special

Page 40: DSL Construction rith Ruby

why is ruby special •  minimally intrusive Syntax to allow for more

concise code

Page 41: DSL Construction rith Ruby

why is ruby special •  minimally intrusive Syntax to allow for more

concise code •  Ruby culture - values expressiveness in

code

Page 42: DSL Construction rith Ruby

why is ruby special •  minimally intrusive Syntax to allow for more

concise code •  Ruby culture - values expressiveness in

code •  Dynamic and Reflective

Page 43: DSL Construction rith Ruby

* Working code writing using RSpec, a testing frame work

Page 44: DSL Construction rith Ruby

DSL goodness

Page 45: DSL Construction rith Ruby

OPTIONAL PUNCTUATION concise code

Page 46: DSL Construction rith Ruby
Page 47: DSL Construction rith Ruby

vs.

Page 48: DSL Construction rith Ruby

SYMBOLS less noisy than strings

Page 49: DSL Construction rith Ruby

or

Page 50: DSL Construction rith Ruby

BLOCKS delayed evaluation of code

Page 51: DSL Construction rith Ruby
Page 52: DSL Construction rith Ruby

OPEN CLASSES build your language

Page 53: DSL Construction rith Ruby
Page 54: DSL Construction rith Ruby

some code here

Page 55: DSL Construction rith Ruby
Page 56: DSL Construction rith Ruby
Page 57: DSL Construction rith Ruby
Page 58: DSL Construction rith Ruby

METAPROGRAMMING expand your mind

Page 59: DSL Construction rith Ruby

define_method eval

module_eval class_eval

instance_eval

alias_method

Page 60: DSL Construction rith Ruby

‘whenever’ a DSL for cron jobs

30 4 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 * * reboot

http://github.com/javan/whenever

Page 61: DSL Construction rith Ruby

language constructs

hour

day month

year

reboot weekend

weekday

sunday monday

a.m p.m

Page 62: DSL Construction rith Ruby

expressive

30 4 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 * * reboot

http://github.com/javan/whenever

Page 63: DSL Construction rith Ruby

The fascinating thing is that, in my experience, most well-written Ruby

programs are already a DSL, just by nature of Ruby’s syntax.”

- Jamis Buck, 37signals

Page 64: DSL Construction rith Ruby

THE PROCESS Writing DSLs in Ruby

Page 65: DSL Construction rith Ruby

Application Programming Interface

try { Socket client = new Socket(“www.google.com”,80); } catch(IOException e) { System.out.println(e); }

Example 1

Page 66: DSL Construction rith Ruby

Application Programming Interface

try { Socket client = new Socket(“www.google.com”,80); } catch(IOException e) { System.out.println(e); }

Customer.find :all, :condition => [ :age >= 25 ]

Example 1

Example 2

Page 67: DSL Construction rith Ruby

Application Programming Interface

try { Socket client = new Socket(“www.google.com”,80); } catch(IOException e) { System.out.println(e); }

Customer.find :all, :condition => [ :age >= 25 ]

•  Libraries give a sense of domain-specificity because of vocabulary

•  Nouns / verbs / adverbs / adjectives

Example 1

Example 2

Page 68: DSL Construction rith Ruby

Application Programming Interface

try { Socket client = new Socket(“www.google.com”,80); } catch(IOException e) { System.out.println(e); }

Customer.find :all, :condition => [ :age >= 25 ]

•  Libraries give a sense of domain-specificity because of vocabulary

•  Nouns / verbs / adverbs / adjectives •  They are all internal DSLs

Example 1

Example 2

Page 69: DSL Construction rith Ruby

DSL

Abstractions

Interfaces

Patterns

“But, I believe a DSL is a healthy bi-product of a good object-oriented design.”

Blaine Buxton (Smalltalk developer)

Page 70: DSL Construction rith Ruby

Capture vocabulary and processes of the domain

Discover desired syntax

Define DSL interface (API)

Define classes and abstractions

Implement validations

Internal DSLs – A coarse process

Page 71: DSL Construction rith Ruby

Capture vocabulary •  Task scheduling is the domain of ‘cron’

•  Tasks •  Timing •  Frequency

Page 72: DSL Construction rith Ruby

Capture vocabulary •  Task scheduling is the domain of ‘cron’

•  Tasks (e.g. ‘reboot’, ‘send mail’, ‘alert’, etc) •  Timing (e.g. ‘5 pm’, ‘4.30 am’, etc) •  Frequency (e.g. ‘yearly’, ‘weekend’, etc)

Page 73: DSL Construction rith Ruby

Capture vocabulary •  Task scheduling is the domain of ‘cron’

•  Tasks (e.g. ‘reboot’, ‘send mail’, ‘alert’, etc) •  Timing (e.g. ‘5 pm’, ‘4.30.am’, etc) •  Frequency (e.g. ‘yearly’, ‘weekend’, etc)

•  Discover keywords •  Special words (‘yearly’, ‘reboot’, etc) •  Domain values (‘5 pm’, etc) •  A good design would decide ownership of these keywords

monday

hourly

day month

year

reboot weekend

weekday

sunday

a.m. p.m.

runner

at

every

annually

Page 74: DSL Construction rith Ruby

Discover syntax

Discuss with

DSL user

Experiment around

keywords

Design a syntax

Define constructs

Define ownership

of keywords

Write extended methods

(e.g. 2.days)

Page 75: DSL Construction rith Ruby

Design considerations

•  “Follow good design principles” –  Entities as classes

•  As nouns

–  Operations as methods •  Typically as verbs •  Adaptive interfaces (wrappers) to instantiate aggregations •  Accept hash as argument to simulate ‘call by name’

Page 76: DSL Construction rith Ruby

Using Ruby features to realize DSL constructs

Purpose (what)

Getter/setter

Pattern matching

Alternative interfaces

Context

Code generation

Execution

Arbitrary interfaces/attributes

Ruby feature (how)

Function calls w/o parentheses

Regular expressions

‘alias_method’

Closure/block

Strings

‘load’, ‘require’, ‘eval’

‘method_missing’

Page 77: DSL Construction rith Ruby

Writing ‘Whenever’

every 2.days, :at => '4:30 am‘ do runner “/usr/bin/reboot” end

Page 78: DSL Construction rith Ruby

Writing ‘Whenever’

every 2.days, :at => '4:30 am‘ do runner “/usr/bin/reboot” end

every(2.days(),{:at => '4:30 am’}) do runner(“/usr/bin/reboot”) end

Page 79: DSL Construction rith Ruby

Writing ‘Whenever’

Class JobList def every(frequency, option={}) … yield #handles block end

def runner(task, options={}) … end end

2.days()

{ :at => ‘4.30.am ‘ }

Page 80: DSL Construction rith Ruby

A TALE OF TWO DSLS Real examples

Page 81: DSL Construction rith Ruby

EXAMPLE 1: DSL FOR GMRT

Page 82: DSL Construction rith Ruby

Giant Metrewave Radio Telescope System

30 Antennae

http://gmrt.ncra.tifr.res.in

Page 83: DSL Construction rith Ruby

GMRT Prototype

•  Objective – Re-engineering ‘ABC’ and ‘Teleset’ – Collaboration among TCS, NCRA and CoEP

•  Challenges – Scientists need a simple, extensible interface to

• Monitor and control antennae •  Schedule experiments

•  Approach –  ABC as collection of Rails web services –  Teleset re-designed as a Ruby DSL

Page 84: DSL Construction rith Ruby

‘Teleset’ as DSL: Version 1.0

a1 = AntennaClient.new (“http://antenna1”) a1.reboot a1.monitor 2.mhz

Single antenna

Page 85: DSL Construction rith Ruby

‘Teleset’ as DSL : Version 1.1

a1 = AntennaClient.new (“http://antenna1”) a1.reboot a1.monitor 2.mhz

Simultaneously, for antennae a1 and a2

engine.register_participant :antenna do | antenna | reboot monitor 2.mhz end

concurrent_iterator on_value => [:a1,:a2], to_variable => ‘antenna’ do participant :antenna => ’${antenna}’

end #Using openwferu engine

Complex !!!

Single antenna

http://openwferu.rubyforge.org - Using OpenWFEru Workflow engine

Page 86: DSL Construction rith Ruby

‘Teleset’ as DSL : Version 2.0

with antenna :a1, :a2 do reboot monitor 2.mhz

end Much

simpler !

engine.register_participant :antenna do | antenna | reboot monitor 2.mhz end

concurrent_iterator on_value => [:a1,:a2], to_variable => ‘antenna’ do participant :antenna => ’${antenna}’

end

Suggested prototype

Page 87: DSL Construction rith Ruby

EXAMPLE 2: DSL FOR VISUALIZATION

Page 88: DSL Construction rith Ruby

DSL for visualization

•  Objective –  A specification-driven dashboard

•  Visualization metaphors (charts, data grids, etc) •  Organization using layouts (window, tab, portal, etc) •  Navigation (page flows)

•  Challenge –  Consistent API –  Integration with other components and environment

•  Ruby was chosen

Page 89: DSL Construction rith Ruby
Page 90: DSL Construction rith Ruby
Page 91: DSL Construction rith Ruby

application ‘ThoughtWorks MCS Demo’ do

add grid ‘Actors list’ do

data_source table do table_name ‘actor’ end # data_source

end # grid end # application

Page 92: DSL Construction rith Ruby

application ‘Thoughtworks MCS Demo’ do add grid ‘Actors list’ do data_source table do table_name ‘actor’ end # data_source

add view ‘Show movies’ do | actor | add grid “Movies for actor #{actor}” do data_source query do text “SELECT … WHERE actor_id=#{actor.actor_id}” end # data_source end # grid end # view end # grid end # application

Page 93: DSL Construction rith Ruby
Page 94: DSL Construction rith Ruby

A STEP FURTHER Advanced topics

Page 95: DSL Construction rith Ruby

Evolution of a DSL •  Generalization versus specialization •  “expressiveness x scope = constant” [3]

DSL

GPL

External DSL

Internal DSLs

ASM GPL

scope scope

expressiveness

expressiveness

Page 96: DSL Construction rith Ruby

Three aspects

Domain aspect

Specification aspect

Language aspect

Domain-specific Language

Page 97: DSL Construction rith Ruby

Three aspects

Domain •  CRUD of

•  Domain entities •  Relationships •  Processes •  Constraints

Specification •  Conditionality (if/

switch) •  Automation

(loops) •  Reusability

(function/classes) •  Data structures •  Error handling

Language •  Natural •  Syntactic noise •  Semantic noise

Page 98: DSL Construction rith Ruby

Three aspects

Domain •  CRUD of

•  Domain entities •  Relationships •  Processes •  Constraints

Specification •  Conditionality (if/

switch) •  Automation

(loops) •  Reusability

(function/classes) •  Data structures •  Error handling

Language •  Natural •  Syntactic noise •  Semantic noise

Page 99: DSL Construction rith Ruby

Three aspects

Domain •  CRUD of

•  Domain entities •  Relationships •  Processes •  Constraints

Specification •  Conditionality (if/

switch) •  Automation

(loops) •  Reusability

(function/classes) •  Data structures •  Error handling

Language •  Natural •  Syntactic noise •  Semantic noise

Page 100: DSL Construction rith Ruby

Evolution of a DSL

Entities (numbers + strings)

Entities (+ relationships)

Conditions and loops

Reusability

Specialization (inheritance)

Page 101: DSL Construction rith Ruby

Crossroads and crosswords

•  “No domain is an island” •  Interoperability in DSLs

•  DSLs need to talk one-another •  Achilles’ Heel for external DSLs •  Parallel development of different DSLs needs early

standardization •  Chicken-egg problem

Page 102: DSL Construction rith Ruby

Future of DSLs •  UML and DSL

•  DSL as front-end to UML (or alternative)[5]

Book “MDA Distilled” (page 16)

Page 103: DSL Construction rith Ruby

Future of DSLs •  UML and DSL

•  DSL as front-end to UML (or alternative)[5]

•  High assurance systems •  Minimal code, relevant code

Page 104: DSL Construction rith Ruby

Future of DSLs •  UML and DSL

•  DSL as front-end to UML (or alternative)[5]

•  High assurance systems •  Minimal code, relevant code

•  Multi-core revolution •  Multi-threading •  Message passing

The Free Lunch Is Over – Herb Sutter’s article on Multi-core Revolution

Page 105: DSL Construction rith Ruby

References and resources 1.  Interview of Bjarne Stroustrup 2.  Presentation by Martin Fowler (at InfoQ.com) 3.  Domain-Specific Languages in Perspective 4.  A Picture is Worth a 1000 Words? 5.  Book “MDA Distilled” (page 16) 6.  The Free Lunch Is Over

Page 106: DSL Construction rith Ruby

Language Design is

Library Design

Library Design is

Language Design

Bjarne Stroustrup [1]