DSL - A first approach to.
This post was originally published at http://solepano.blogspot.com
This is a summary of the Martin Fowler's article on Language Workbenches: The Killer-App for Domain Specific Languages? which I have recently read and found very interesting.
Terminology
DSL
Imagine you build a class library to solve some
particular problem and that the objects involved are
parameterizable. So, you need a first step to set up
configuration and wire up composite objects before putting
them to do the work.
When building this kind of class library, there is a
marked distinction between the abstraction itself and the
configuration. The abstraction may be reusable and less
often to change, while the configuration tends to be
specific, more simple, and likely to change more
often.
This leads to the idea of putting the configuration out
of the code, for example, in xml files or in some custom
syntax file (what may be more readily). The structure of
this configuration, the mapping with the objects in the
abstraction, the parameters, etc, are nothing but a kind
of Domain Specific Language, a very small programming
language, suitable for the only purpose of solving some
specific problem.
If we leave the configuration in the code, instead of
moving it to a configuration file, we still have a case of
DSL, a DSL embedded in the host language. So here comes
the distinction between
internal and external DSL.
External DSL: DSL written in a different language than
the main language of an application.
Internal DSL: DSL written in the same language of the
main language of an application.
Language Oriented Programming
Language oriented programming is about describing a
system through multiple DSLs. It does not have to be a
black or white thing; you can represent little or a lot of
functionality of your system in DSLs.
Pros and Cons of Language Oriented Programming
|
External DSL |
|
|
Pros |
Cons |
|
|
|
Internal DSL |
|
|
Pros |
Cons |
|
|
Language Workbenches
Language Workbenches are complex tools that help
implementing DSLs. They are based on the same model as
post-IntelliJ IDEs, which consists of having four
different representations of the code:
Abstract representation: In-memory representation. Helps with things like name
completion and refactoring. It is the key persistent
source that you manipulate (through the editable
representation). It can persist incomplete or
contradictory information.
Editable representation: Projection of the abstract representation in order to
edit it. It does not have to be complete. There can be
multiple projections, one for each aspect.
Storage
representation: Serialization of the
abstract representation, often as XML.
Executable
representation: The CLR byte code. A code
generator turns the abstract representation into the
executable representation.
So, when defining a new DSL you need to:
-
Define the abstract syntax, the schema of the
abstract representation.
-
Define an editor to let people manipulate the
abstract representation through a projection.
-
Define a generator to translate the abstract
representation into an executable representation. In
practice the generator defines the semantics of the
DSL.