next up previous contents
Next: 4.4 Concept Development and Up: 4. Programming Concepts Previous: 4.2 Evolution of Programming

4.3 Domain-Specific Embedded Language

Closely related to the programming paradigms which have been discussed above is an emerging concept for high-level languages, such as C++, domain-specific embedded languages.

First, a domain-specific language (DSL) is defined by a set of symbols as well as by a well-defined set of rules specifying how the symbols are used to build well-formed compositions [45]. The domain-specific part of a DSL can then be employed by a simplified grammar and an increased expressiveness. The possibility of writing code in terms close to the level of abstraction of the initial problem domain is the characteristic property of DSLs.

The next relevant issue regarding a DSL is interoperability. A possible way of dealing with interoperability is to integrate the domain-specific language into a host language, finally obtaining a domain-specific embedded language (DSEL), e.g., YACC [105]. All software engineering tasks, such as designing, implementing, and maintaining the DSL, are reduced to implementing and maintaining a library of the host language. And more importantly, the interoperability can be enhanced to the highest level, due to the fact that both concepts are now available in one host language. All the libraries already developed and their functionality are available at the same time. To summarize, the advantages of domain-specific embedded languages are:

The advent of having multiple paradigms available in a single programming language creates new possibilities for domain-specific languages. The advantages and disadvantages of several programming paradigms and the reduction of specification and implementation effort clearly suggest the use of domain-specific embedded languages, such as reducing the stated implementation effort of the object-oriented and generic programming paradigm to $ \mathcal{O}(1 + 1)$ . This means that the effort of building applications can be reduced to a constant effort by utilizing a DSEL without additional transformation steps. Maintenance and further development for an extra transformation tool is thereby greatly reduced, compared to, e.g., the transformation tool for Sophus [106]. But up to now, the implementation of a DSEL for non-trivial areas is far from simple or user-oriented. Also, domain-specific languages require various mechanisms from the host languages, where the following features are almost mandatory:

Table 4.1: Language comparison.
Language operator overloading parametric polymorphism functional mechanisms time of evolution
C no partial (macros) no compile/run-time
D partial yes no compile/run-time
Java no partial (version) no run-time
C# no partial (version) no run-time
Haskell yes partial (version) yes run-time
C++ yes yes yes compile/run-time

As can be seen from the brief comparison of languages provided in Table 4.1, only a few languages are available which allow an efficient modeling of operators. Languages such as Haskell were not developed with an overall high performance approach, but they still offer the definition of new operators which extend the built-in language syntax. Based on this overview, the only language offering the best support for DSELs with syntactic expressiveness as well as run-time efficiency is C++. In addition to the great possibilities of using C++ as a host language for a DSEL, the multi-paradigm approach offers a great degree of freedom in the implementation of high performance scientific code and even applications [107,108]. The main feature is the paradigm of template meta-programming of C++, introduced in Section 4.2, which means that a DSEL can function as an extension to the general-purpose host language. Meta-programming and DSEL are also actively developed areas [48,49]. An example is given next which illustrates the embedded nature of a grammar specification in C++. The first part yields the normal grammar specification by YACC:

group ::= '(' expression ')'
factor ::= inte...
...' factor))*
expression ::= term (('+' term) \vert ('-' term))*

Next, an example of Spirit [75] is given, where Spirit is an object-oriented, recursive-descent parser and output generation framework enabling target grammars written entirely in C++ as a DSEL.

group = '(' » expression » ')';
factor = i...
expression = term » *(('+' » term) \vert ('-' » term));

Another advantage of the DSEL concept is the further development of compiler technology, which drastically increases the performance of high-level code. Recent performance analysis has shown that each compiler generation increases the overall run-time performance [109].

next up previous contents
Next: 4.4 Concept Development and Up: 4. Programming Concepts Previous: 4.2 Evolution of Programming

R. Heinzl: Concepts for Scientific Computing