that is defined as a library for a generic "host" programming language. The embedded DSL inherits the generic language constructs of its host language - sequencing, conditionals, iteration, functions, etc. - and adds domain-specific primitives that allow programmers to work at a much higher level of abstraction. Multiple EDSLs can easily be combined into a single program and a programmer can use the facilities of the host language to extend the existing DSLs or use them to build an even higher level DSL.
Also called 'InternalDomainSpecificLanguage
' by some experts, including MartinFowler
s', which essentially have a separate compiler or interpreter (and thus require a separate development environment).
For this style of programming to work well, the syntax of the generic language must be flexible and expressive enough to "get out of the way" of the embedded DSL. That usually means that the host language has a very minimal syntax. The technique can easily be used in the LispLanguage
, ToolCommandLanguage ForthLanguage
, but is much harder to use in the JavaLanguage
, for example.
I don't think the host language need to be minimal. For example, RubyLanguage or PerlLanguage has a rich syntax, but can be used quite simply to build DSLs (I remember a hardware description language and a QuantumComputing simulation language written as Ruby sub-languages, and there is Lingua::Romana::Perligata)
I agree with the statement above. Without a rich syntax, your EDSL will have a hard time approximating existing notations. It shouldn't be necessary to redesign EBNF just to embed a parser in your program, but if all you have to work with is parentheses and symbols, that's what'll happen
, co-author of CppTemplateMetaprogramming
"I think the confusion stems from Ruby's Lisp Heritage. Lisp is a homoiconic language, meaning that its syntax is also a form of data that can be manipulated by Lisp programs. Thus, Lisp is a metalanguage for itself. The point of this is that lisp programs can extend Lisp with constructs that have syntax very much like lisp but with added semantics unavailable to the Lisp Language itself. While Ruby shares many ideas with Lisp, Ruby is not a homoiconic language. When one writes Ruby libraries it is a stretch to call them DSLs since both the syntax an semantics that the library makes use of are that of Ruby. However, it is not the case that DSL's cannot be written in Ruby since the language has metaprogramming features that facilitate this activity."
(book) for a discussion of this in the context of CeePlusPlus
. See also BoostProtoLibrary
which provides a toolkit and some examples.
Some objections from someone:
You aren't really defining new internal languages, but rather making use of the language you are using. More like DomainSpecificTweaks
". Stretching the definitions a bit far. A true internal domain specific language would be SQL parsed as SQL in any language as is (without mapping it to OOP or using a different SQL that isn't SQL).
What does it ever mean to parse a language "as is"? I'm fairly certain that you need to map the language to something, even if it isn't OOP.
here, but you aren't really defining new languages by making use of Ruby or Perl's syntax. You are using ruby and perl, in fact, as your language. Languages that provide abilities to utilize rich/modifiable notation/syntax are DomainSpecificTweaks
to an existing language.
They are embedded and domain-specific 'tweaks', true, but two distinct sets of tweaks that serve the same purpose could easily lead to two different and incompatible DomainSpecificLanguages for the very same domain. So I can't agree with an argument that these are "just" DomainSpecificTweaks.
They are extensions, tweaks.
See Also: DomainSpecificLanguage