|abstract ||For automation it is important to express the knowledge of the experts in a form
that is understood by a computer. Each area of knowledge has its own terminology and ways of formulating things; be it by drawing diagrams, using formulae, or using formalized languages. In the last case we say we have a "Domain Specific Language",
and --since it is formalised-- it can usually be processed or analysed by a computer or even
be compiled into machine code. Domain-specific languages often do not have a formal specification and are usually designed and implemented in an ad-hoc fashion, frequently leading to inconsistent designs. Furthermore they often lack features that are usually
found in programming languages, such as abstraction mechanisms, type systems, and static analysis. Such features are often considered to take too much effort to implement.
Initially these features are not really missed, however, when programs grow, they become indispensable. Defining a complete and consistent language from scratch is not an easy task, and so the question arises: how to support the design and implementation of domain-specific languages? A solution is to embed a domain-specific language in a general-purpose host language. This approach has many advantages. One does not have to implement an entirely new compiler, one can simply reuse the features of the host language, such as the type system and abstraction mechanisms. Futhermore, different embedded languages can be combined together in a single program. In the Haskell community embedding domain-specific languages by means of combinator libraries is common practice. The rich type system and flexible notational features, such as user-defined operators, type classes, and do-notation, make Haskell very suitable for embedding domain-specific languages. Originally combinator-based embedded languages directly expressed the denotational semantics of the embedded language. As a consequence, techniques used in conventional compilers are not applicable because
the representation of the embedded progam is implicit. A logical next step along this line of development is to first build an intermediate structure, which can then be analyzed, transformed and optimized as in an ordinary compiler. How to do such things effectively in a strongly typed host language is the subject of this thesis: Embedded Compilers.|