Title: A Little Language for Surveys: Constructing an Internal DSL in Ruby
1A Little Language for Surveys Constructing an
Internal DSL in Ruby
- H. Conrad Cunningham
- Computer and Information ScienceUniversity of
Mississippi
2Domain-Specific Language (DSL)
- programming language or executable specification
language that offers, through appropriate
notations and abstractions, expressive power
focused on, and usually restricted to, a
particular problem domain van Deursen,
Klint, and Visser - little language J. Bentley
3Typical DSL Characteristics
- Not general-purpose
- Small (at least initially)
- Declarative
- Semantically expressive of domain
- Targeted at domain specialists, not
necessarily programmers
4External or Internal
- External different from main programming
language - make, yacc, pic, XML-based config files
- Internal (embedded) constrained use of the main
programming language - use of Lisp macros, Haskell algebraic types,
metaprogramming in Ruby, etc.
5Defining Internal DSLs in Ruby (1 of 2)
- Flexible syntax enables convenient DSL statements
- optional parentheses on method calls
- variable number of arguments
- question Male or female?
- has optional second arg
6Defining Internal DSLs in Ruby (2 of 2)
- Blocks (closures) provide DSL structuring and
delayed execution - anonymous function definitions
- passed as arguments
- question Male or female? do
- response Male
- response Female do _at_fem true end
- end
7Implementing Internal DSLs in Ruby (1 of 2)
- Reflexive metaprogramming
- writing programs that manipulate themselves as
data - obj.instance_eval(str) executes string str as
Ruby code in context of object obj - execute DSL statements dynamically
- mod.class_eval(str) executes string str as Ruby
code in context of module mod - declare new methods and classes dynamically
8Implementing Internal DSLs in Ruby (2 of 2)
- obj.method_missing(sym,args) invoked when
undefined method sym called with arguments args - take remedial action
- obj.send(sym,args) calls method sym on object
obj with arguments args - dynamically send a message
9Little Language for Surveys
- Domain Specification and presentation of
simple, multiple-choice surveys - Tasks
- Analyze domain for language design
- Design Ruby internal DSL
- Implement DSL
10Domain Analysis
11Commonality/Variability Analysis
- Determine domain boundaries (scope)
- Define specialized terms and concepts
(terminology) - Identify unchanging features among domain members
(commonalities) - Identify features that may change among domain
members (variabilities)
12Scope
- Support definition of simple, multiple-choice
surveys - specification of survey
- presentation of survey and collection of
responses - Exclude tabulation of aggregate results for now
13Terms and Commonalities
- Survey has a title
- Survey has a sequence of questions
- Question has a sequence of responses
- Use of conditional question depends upon previous
responses - Response to silent question determined from
previous responses - Survey execution presents appropriate questions
to respondent and collects choices of responses
14Variabilities
- Texts for title, questions, and responses
- Number and order of questions within survey
- Number of responses expected for question
- Number and order of responses in question
- Condition under which question included
- Method for answering silent question
- Source of survey specification
- Method for displaying questions and collecting
responses during execution
15Internal DSL Design
16DSL Design Strategy
- Adopt declarative approach structure explicit
but processing implicit - Use terminology and commonalities to suggest
language statements - Represent variabilities as values that survey
programmers supply
17Survey DSL Example (1 of 3)
- C1 survey has title (V1)
- title ACMSE Survey
- C2 survey has seq of questions (V2)
- question Are you an author? do (V3)
- C3 question has seq of responses (V4)
- response "Yes" do execute if chosen
- _at_author true
- end
- response No do execute if chosen
- _at_author false
- end
- end
18Survey DSL Example (2 of 3)
- C4 conditional question (V5)
- question "What type of paper?" do
- condition _at_author when execute?
- response "Regular" do _at_p rg end
- response "Student" do _at_p st end
- response "Work-in-progress" do
- _at_p wp
- end
- V5/V6 block on response action sets
- state for conditions silent choices
- action _at_t 25 _at_t 15 if _at_p wp
- end
19Survey DSL Example (3 of 3)
- C5 silent question calculates choice (V6)
- result "How long is presentation? do
- condition _at_author
- alternative "25" do when choose?
- _at_p rp _at_p sp
- end
- alternative 15 do when choose?
- _at_p wp
- end
- end
20Internal DSL Implementation
21Two-Pass Implementation
- Parse DSL and build abstract syntax tree (AST)
- Execute survey by traversing AST
22First Pass DSL Parsing
- Use instance_eval to execute DSL input as Ruby
code (V7) - Let Ruby interpreter do most of parsing
- Add methods for each DSL statement
title, question, action, etc. - Check specialized syntax and build AST as
3-level tree (survey, question, response) - Defer conditions and actions by storing
unevaluated blocks
23Second Pass DSL Interpretation
- Traverse AST to display questions and collect
responses - Execute deferred blocks needed for conditions and
actions - Use missing_method and class_eval to create
reader/writer methods for variables in blocks
24Architecture
- First pass use Object Scoping and Context
Variable patterns for safety and flexibility,
Deferred Evaluation for actions - Second pass use Visitor pattern for flexibility
(C6, V8)
25Summary
- Illustrated how commonality/variability analysis
can be adapted for DSL design - Demonstrated how Ruby facilities can be used for
internal DSL development - Explored how design patterns can help lead to
safe and flexible DSL processors
26Future Work
- More systematic techniques to explore domain and
discover needed constructs - Improved runtime error handling tied to DSL input
- Better facilities for user extension
- Investigation and comparison of other languages
Groovy, Scala, Haskell
27Acknowledgements
- Members of Fall 2006 graduate class on Ruby and
Software Development - Suggestions on the paper by several current and
former students
28Questions