Table of Contents

Copyright

Brief Table of Contents

Table of Contents

Foreword

Preface

Acknowledgments

About the Book

1. Introducing domain-specific languages

Chapter 1. Learning to speak the language of the domain

1.1. The problem domain and the solution domain

1.1.1. The problem domain

1.1.2. The solution domain

1.2. Domain modeling: establishing a common vocabulary

1.2.1. Benefits of a common vocabulary

1.3. Introducing DSLs

1.3.1. What’s a DSL?

1.3.2. Popular DSLs in use

1.3.3. Structure of a DSL

1.4. Execution model of a DSL

1.5. Classifying DSLs

1.5.1. Internal DSLs

1.5.2. External DSLs

1.5.3. Nontextual DSLs

1.6. When do you need a DSL?

1.6.1. The advantages

1.6.2. The disadvantages

1.7. DSLs and abstraction design

1.8. Summary

1.9. References

Chapter 2. The DSL in the wild

2.1. Building your first Java DSL

2.1.1. Setting up the common vocabulary

2.1.2. Your first Java implementation

2.2. Making friendlier DSLs

2.2.1. Externalizing the domain with XML

2.2.2. Groovy: a more expressive implementation language

2.2.3. Executing the Groovy DSL

2.3. DSL implementation patterns

2.3.1. Internal DSL patterns: commonality and variability

2.3.2. External DSL patterns: commonality and variability

2.4. Choosing DSL implementations

Reusing existing infrastructure

Leveraging existing knowledge

Learning curve with external DSLs

The right level of expressivity

Composability

2.5. Summary

2.6. References

Chapter 3. DSL-driven application development

3.1. Exploring DSL integration

3.1.1. Why you should care about DSL integration

3.2. Internal DSL integration patterns

3.2.1. Using the Java 6 scripting engine

3.2.2. Using a DSL wrapper

3.2.3. Language-specific integration features

3.2.4. Spring-based integration

3.3. External DSL integration patterns

3.4. Handling errors and exceptions

3.4.1. Naming an exception

3.4.2. Handling incorrect typing errors

3.4.3. Handling exceptional business conditions

3.5. Managing performance

3.6. Summary

3.7. References

2. Implementing DSLs

Chapter 4. Internal DSL implementation patterns

4.1. Filling your DSL toolbox

4.2. Embedded DSLs: patterns in metaprogramming

4.2.1. Implicit context and Smart APIs

4.2.2. Reflective metaprogramming with dynamic decorators

4.2.3. Reflective metaprogramming with builders

4.2.4. Lessons learned: metaprogramming patterns

4.3. Embedded DSLs: patterns with typed abstractions

4.3.1. Higher-order functions as generic abstractions

4.3.2. Using explicit type constraints to model domain logic

4.3.3. Lessons learned: thinking in types

4.4. Generative DSLs: boilerplates for runtime generation

4.4.1. How generative DSLs work

4.4.2. Ruby metaprogramming for concise DSL design

4.5. Generative DSLs: macros for compile-time code generation

4.5.1. Metaprogramming with Clojure

4.5.2. Implementing the domain model

4.5.3. The beauty of Clojure macros

4.6. Summary

4.7. References

Chapter 5. Internal DSL design in Ruby, Groovy, and Clojure

5.1. Making DSLs concise with dynamic typing

5.1.1. Readability

5.1.2. Duck typing

5.1.3. Metaprogramming—again!

5.1.4. Why Ruby, Groovy, and Clojure?

5.2. A trade-processing DSL in Ruby

5.2.1. Getting started with an API

5.2.2. A little bit of monkey-patching

5.2.3. Rolling out a DSL interpreter

5.2.4. Adding domain rules as decorators

5.3. The order-processing DSL: the final frontier in Groovy

5.3.1. The order-processing DSL so far

5.3.2. Controlling the scope of metaprogramming

5.3.3. Rounding it off

5.4. Thinking differently in Clojure

5.4.1. Building a domain object

5.4.2. Enriching domain objects using decorators

5.4.3. A DSL session at the REPL

5.5. Recommendations to follow

5.5.1. Honor the principle of least complexity

5.5.2. Strive for optimal expressivity

5.5.3. Avoid diluting the principles of well-designed abstractions

5.5.4. Avoid language cacophony

5.6. Summary

5.7. References

Chapter 6. Internal DSL design in Scala

6.1. Why Scala?

6.2. Your first step toward a Scala DSL

6.2.1. Testing Java objects with a Scala DSL

6.2.2. Scala DSL as a wrapper for Java objects

6.2.3. Modeling noncritical functionality as a Scala DSL

6.3. Let’s DSL in Scala!

6.3.1. Expressive syntax on the surface

6.3.2. Creating domain abstractions

6.4. Building a DSL that creates trades

6.4.1. Implementation details

6.4.2. Variations in DSL implementation patterns

6.5. Modeling business rules with a DSL

6.5.1. Pattern matching as an extensible Visitor

6.5.2. Enriching the domain model

6.5.3. Calculating tax and fee business rules in a DSL

6.6. Stitching ’em all together

6.6.1. More abstraction with traits and types

6.6.2. Making domain components concrete

6.7. Composing DSLs

6.7.1. Composing using extensions

6.7.2. Composing different DSLs using hierarchical composition

6.8. Monadic structures in DSL

What’s a monad?

How monads reduce accidental complexity

Designing a monadic Trade DSL

6.9. Summary

6.10. References

Chapter 7. External DSL implementation artifacts

7.1. Anatomy of an external DSL

7.1.1. The simplest option first

7.1.2. Abstracting the domain model

7.2. The role of a parser in designing an external DSL

7.2.1. Parsers and parser generators

7.2.2. Syntax-directed translation

7.3. Classifying parsers

7.3.1. Simple top-down parsers

7.3.2. Advanced top-down parsers

7.3.3. Bottom-up parsers

7.4. Tool-based DSL development with Xtext

7.4.1. Grammar rules and the outline view

7.4.2. The metamodel for your grammar

7.4.3. Generating code for the semantic model

7.5. Summary

7.6. References

Chapter 8. Designing external DSLs using Scala parser combinators

8.1. Parser combinators

8.1.1. What are parser combinators?

8.1.2. Designing DSLs the parser combinator way

8.2. The Scala parser combinator library

8.2.1. The base abstractions in the parser combinator library

8.2.2. The combinators that glue parsers together

8.2.3. Monads for DSL parser composition

8.2.4. Packrat parsing for left recursive DSL syntax

8.3. DSL design with parser combinators: step-by-step

8.3.1. Step 1: Executing the grammar

8.3.2. Step 2: Building the semantic model for the DSL

8.3.3. Step 3: Designing the Order Abstraction

8.3.4. Step 4: Generating the AST using function application combinators

8.4. A DSL that needs a packrat parser

8.4.1. Introducing the domain problem

8.4.2. Building the grammar

8.4.3. Designing the semantic model

8.4.4. Parser composition for extending DSL semantics

8.5. Summary

8.6. References

3. Future trends in DSL development

Chapter 9. DSL design: looking forward

9.1. Growing language support for DSL design

9.1.1. Striving to be expressive

9.1.2. More power with metaprogramming

9.1.3. s-expressions instead of XML as the carrier

9.1.4. Parser combinators becoming more popular

9.2. DSL workbenches

9.2.1. What’s in a DSL workbench?

9.2.2. The advantages of using a DSL workbench

9.3. More tool support

9.4. The mature evolution of a DSL

9.4.1. Versioning your DSL

9.4.2. Best practices for a smoother evolution of DSL

9.5. Summary

9.6. References

Appendix A. Role of abstractions in domain modeling

A.1. Qualities of well-designed abstractions

A.1.1. Minimalism

A.1.2. Distillation

A.1.3. Extensibility and composability

A.2. Minimalism publishes only what you promise

A.2.1. Evolve by being generic

A.2.2. Subtyping to prevent implementation leak

A.2.3. Implementation inheritance done right

A.3. Distillation keeps only what YOU need

A.3.1. What is nonessential?

A.3.2. Accidental complexity

A.3.3. Removing the impurities

A.3.4. Keeping away implementation details using DI

A.4. Extensibility helps piecemeal growth

A.4.1. What’s extensibility?

A.4.2. Mixins: a design pattern for extensibility

A.4.3. Mixins for extending Map

A.4.4. Functional extensibility

A.4.5. Extensibility can be monkey business too

A.5. Composability comes from purity

A.5.1. Design patterns for composability

A.5.2. Back to languages

A.5.3. Side effects and composability

A.5.4. Composability and concurrency

A.6. References

Appendix B. Metaprogramming and DSL design

B.1. The meta in the DSL

B.1.1. Runtime metaprogramming in DSL implementation

B.1.2. Compile-time metaprogramming in DSL implementation

B.2. Lisp as the DSL

B.2.1. What’s so special about Lisp?

B.2.2. Code as data

B.2.3. Data as code

B.2.4. A simple parser that parses only list structures

B.3. References

Appendix C. A cheat sheet for Ruby’s DSL-friendly features

C.1. DSL-friendly features of Ruby

C.2. References

Appendix D. A cheat sheet for Scala’s DSL-friendly features

D.1. DSL-friendly features of Scala

D.2. References

Appendix E. A cheat sheet for Groovy’s DSL-friendly features

E.1. DSL-friendly features of Groovy

E.2. References

Appendix F. A cheat sheet for Clojure’s DSL-friendly features

F.1. DSL-friendly features of Clojure

F.2. References

Appendix G. Polyglot development

G.1. What features should you look for in an IDE?

G.2. Bootstrapping a Java-Groovy development environment

G.3. Bootstrapping a Java-Scala development environment

G.4. Popular IDEs for polyglot development

Index

List of Figures

List of Tables

List of Listings

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.109.4