Foreword |
|
xiii | |
Preface |
|
xv | |
Acknowledgments |
|
xvii | |
About the book |
|
xix | |
|
PART I INTRODUCING DOMAIN-SPECIFIC LANGUAGES |
|
|
1 | (84) |
|
1 Learning to speak the language of the domain |
|
|
3 | (22) |
|
1.1 The problem domain and the solution domain |
|
|
4 | (2) |
|
|
4 | (1) |
|
|
4 | (2) |
|
1.2 Domain modeling: establishing a common vocabulary |
|
|
6 | (2) |
|
Benefits of a common vocabulary |
|
|
7 | (1) |
|
|
8 | (7) |
|
|
10 | (2) |
|
|
12 | (2) |
|
|
14 | (1) |
|
1.4 Execution model of a DSL |
|
|
15 | (2) |
|
|
17 | (3) |
|
|
18 | (1) |
|
|
18 | (1) |
|
|
19 | (1) |
|
1.6 When do you need a DSL? |
|
|
20 | (2) |
|
|
20 | (1) |
|
|
21 | (1) |
|
1.7 DSLs and abstraction design |
|
|
22 | (1) |
|
|
23 | (1) |
|
|
24 | (1) |
|
|
25 | (29) |
|
2.1 Building your first Java DSL |
|
|
26 | (6) |
|
Selling up the common vocabulary |
|
|
27 | (1) |
|
Your first Java implementation |
|
|
28 | (4) |
|
2.2 Making friendlier DSLs |
|
|
32 | (4) |
|
Externalizing the domain wilh XML |
|
|
32 | (1) |
|
Groovy: a more expressive implementation language |
|
|
33 | (2) |
|
|
35 | (1) |
|
2.3 DSL implementation patterns |
|
|
36 | (14) |
|
Internal DSL patterns: commonality and variability |
|
|
37 | (8) |
|
External DSL patterns: commonality and variability |
|
|
45 | (5) |
|
2.4 Choosing DSL implementations |
|
|
50 | (2) |
|
|
52 | (1) |
|
|
53 | (1) |
|
3 DSL-driven application development |
|
|
54 | (31) |
|
3.1 Exploring DSL integration |
|
|
55 | (3) |
|
Why you should rare about DSL integration |
|
|
56 | (2) |
|
3.2 Internal DSL integration patterns |
|
|
58 | (18) |
|
Using the Java 6 scripting engine |
|
|
60 | (4) |
|
|
64 | (9) |
|
Language-specific integration features |
|
|
73 | (2) |
|
|
75 | (1) |
|
3.3 External DSL integradon patterns |
|
|
76 | (2) |
|
3.4 Handling errors and exceptions |
|
|
78 | (4) |
|
|
79 | (1) |
|
Handling incorrect typing errors |
|
|
80 | (1) |
|
Handling exceptional business conditions |
|
|
81 | (1) |
|
|
82 | (1) |
|
|
83 | (1) |
|
|
84 | (1) |
|
PART II IMPLEMENTING DSLS |
|
|
85 | (190) |
|
4 Internal DSL implementation patterns |
|
|
87 | (41) |
|
4.1 Filling your DSL toolbox |
|
|
88 | (2) |
|
4.2 Embedded DSLs: patterns in metaprogramming |
|
|
90 | (16) |
|
Implicit context and Smart APIs |
|
|
91 | (5) |
|
Reflective metaprogramming with dynamic decorators |
|
|
96 | (6) |
|
Reflective metaprogramming with builders |
|
|
102 | (3) |
|
Lessons learned: metaprogramming patterns |
|
|
105 | (1) |
|
4.3 Embedded DSLs: patterns with typed abstractions |
|
|
106 | (12) |
|
Higher-order functions as generic abstractions |
|
|
106 | (7) |
|
Using explicit type constraints to model domain logic |
|
|
113 | (4) |
|
Lessons learned: thinking in types |
|
|
117 | (1) |
|
4.4 Generative DSLs: boilerplates for runtime generation |
|
|
118 | (4) |
|
|
118 | (1) |
|
Ruby metaprogramming for concise DSL design |
|
|
119 | (3) |
|
4.5 Generative DSLs: macros for compile-time code generation |
|
|
122 | (4) |
|
Metaprogramming with Clojure |
|
|
122 | (1) |
|
Implementing the domain model |
|
|
123 | (2) |
|
The beauty of Clojure macros |
|
|
125 | (1) |
|
|
126 | (1) |
|
|
127 | (1) |
|
5 Internal DSL design in Ruby, Groovy, and Clojure |
|
|
128 | (38) |
|
5.1 Making DSLs concise with dynamic typing |
|
|
129 | (6) |
|
|
130 | (1) |
|
|
131 | (2) |
|
|
133 | (1) |
|
Why Ruby, Groovy, and Clojure? |
|
|
134 | (1) |
|
5.2 A trade-processing DSL in Ruby |
|
|
135 | (13) |
|
Getting started with an API |
|
|
136 | (3) |
|
A little bit of monkey-patching |
|
|
139 | (1) |
|
Rolling out a DSL interpreter |
|
|
140 | (3) |
|
Adding domain rules as decorators |
|
|
143 | (5) |
|
5.3 The order-processing DSL: the final frontier in Groovy |
|
|
148 | (5) |
|
The order-processing DSL so far |
|
|
148 | (1) |
|
Controlling the scope of metaprogramming |
|
|
149 | (3) |
|
|
152 | (1) |
|
5.4 Thinking differently in Clojure |
|
|
153 | (9) |
|
|
154 | (1) |
|
Enriching domain objects using decroators |
|
|
155 | (6) |
|
A DSL session at the REPL |
|
|
161 | (1) |
|
5.5 Recommendations to follow |
|
|
162 | (2) |
|
Honor the principle of least complexity |
|
|
162 | (1) |
|
Strive for optimal expressivity |
|
|
162 | (1) |
|
Avoid diluting the principles of well-designed abstractions |
|
|
163 | (1) |
|
|
163 | (1) |
|
|
164 | (1) |
|
|
165 | (1) |
|
6 Internal DSL design in Scala |
|
|
166 | (45) |
|
|
167 | (2) |
|
6.2 Your first step toward a Scala DSL |
|
|
169 | (1) |
|
Testing Java objects with a Scala DSL |
|
|
169 | (1) |
|
Scala DSL as a wrapper for Java objects |
|
|
170 | (1) |
|
Modeling noncritical Juncitonality as a Scala DSL |
|
|
170 | (1) |
|
|
170 | (5) |
|
Expressive syntax on the surface |
|
|
171 | (1) |
|
Creating domain abstractions |
|
|
172 | (3) |
|
6.4 Building a DSL that creates trades |
|
|
175 | (7) |
|
|
177 | (4) |
|
Variations in DSL implmentation patterns |
|
|
181 | (1) |
|
6.5 Modeling business rules with a DSL |
|
|
182 | (8) |
|
Pattern matching as an extensible Visitor |
|
|
183 | (1) |
|
Enriching the domain model |
|
|
184 | (3) |
|
Calculating tax and fee business rules in a DSL |
|
|
187 | (3) |
|
6.6 Stitching 'em all together |
|
|
190 | (3) |
|
More abstraction with traits and types |
|
|
190 | (2) |
|
Making domain components concrete |
|
|
192 | (1) |
|
|
193 | (10) |
|
Composing using extensions |
|
|
194 | (5) |
|
Composing different DSLs using hierarchical composition |
|
|
199 | (4) |
|
6.8 Monadic structures in DSL |
|
|
203 | (5) |
|
|
208 | (1) |
|
|
209 | (2) |
|
7 External DSL implementation artifacts |
|
|
211 | (64) |
|
7.1 Anatomy of an external DSL |
|
|
212 | (5) |
|
The simplest option first |
|
|
212 | (1) |
|
Abst racting the domain model |
|
|
213 | (4) |
|
7.2 The role of a parser in designing an external DSL |
|
|
217 | (8) |
|
Parsers and parser generators |
|
|
217 | (2) |
|
Syntax-directed translation |
|
|
219 | (6) |
|
|
225 | (6) |
|
|
226 | (2) |
|
Advanced top-down parsers |
|
|
228 | (1) |
|
|
229 | (2) |
|
7.4 Tool-based DSL development with Xtext |
|
|
231 | (7) |
|
Grammar rules and the outline view |
|
|
232 | (1) |
|
The melamodel for your grammar |
|
|
233 | (3) |
|
Generating code for the semantic model |
|
|
236 | (2) |
|
|
238 | (1) |
|
|
239 | (3) |
|
Designing external DSLs using Scala parser combinators |
|
|
241 | (1) |
|
|
242 | (4) |
|
What are parser combinators? |
|
|
243 | (1) |
|
Designing DSLs the parser combinator way |
|
|
244 | (2) |
|
8.2 The Scala parser combinator library |
|
|
246 | (11) |
|
The base abstractions in the parser combinator library |
|
|
247 | (1) |
|
The combinators that glue parsers together |
|
|
248 | (4) |
|
Monads for DSL parser composition |
|
|
252 | (2) |
|
Packrat parsing for left recursive DSL syntax |
|
|
254 | (3) |
|
8.3 DSL design with parser combinators: step-by-step |
|
|
257 | (7) |
|
Step 1 Executing the grammar |
|
|
258 | (1) |
|
Step 2 Building the semantic model for the DSL |
|
|
259 | (1) |
|
Step 3 Designing the Order abstraction |
|
|
260 | (1) |
|
Step 4 Generating the AST using function application combinators |
|
|
261 | (3) |
|
8.4 A DSL that needs a packrat parser |
|
|
264 | (8) |
|
Introducing the domain problem |
|
|
264 | (2) |
|
|
266 | (2) |
|
Designing the semantic model |
|
|
268 | (2) |
|
Parser composition for extending DSL semantics |
|
|
270 | (2) |
|
|
272 | (1) |
|
|
273 | (2) |
|
PART III FUTURE TRENDS IN DSL DEVELOPOMENT |
|
|
275 | (16) |
|
9 DSL design: looking forward |
|
|
277 | (14) |
|
9.1 Growing language support for DSL design |
|
|
278 | (4) |
|
Striving to be expressive |
|
|
279 | (2) |
|
More power with metapgrogramming |
|
|
281 | (1) |
|
s-expressions instead of XML as the carrier |
|
|
281 | (1) |
|
Parser combinators becoming more popular |
|
|
282 | (1) |
|
|
282 | (3) |
|
What's in a DSL workbench? |
|
|
283 | (1) |
|
The advantages of using a DSL workbench |
|
|
284 | (1) |
|
|
285 | (1) |
|
9.4 The mature evolution of a DSL |
|
|
286 | (3) |
|
|
286 | (1) |
|
Best practices for a smoother evolution of DSL |
|
|
287 | (2) |
|
|
289 | (1) |
|
|
290 | (1) |
appendix A Role abstractions in domain modeling |
|
291 | (20) |
appendix B Metaprogramming and DSL design |
|
311 | (10) |
appendix C A cheat sheet for Ruby's DSL-friendly features |
|
321 | (4) |
appendix D A cheat sheet for Scala's DSL-friendly features |
|
325 | (5) |
appendix E A cheat sheet for Groovy's DSL-friendly features |
|
330 | (3) |
appendix F A cheat sheet for Clojure's DSL-friendly features |
|
333 | (4) |
appendix G Polyglot development |
|
337 | (4) |
Index |
|
341 | |