Sham: A DSL for Fast DSLs
Domain-specific languages (DSLs) are touted as both easy to embed in programs and easy to optimize. Yet these goals are often in tension. Embedded or internal DSLs fit naturally with a host language, while inheriting the host's performance characteristics. External DSLs can use external optimizers and languages but sit apart from the host. We present Sham, a toolkit designed to enable internal DSLs with high performance. Sham is itself a DSL embedded in Racket, but compiles transparently to LLVM at runtime. Sham is designed to be well suited as both a compilation target for other DSLs embedded in Racket as well as a language for transparently replacing DSL support code with faster versions. Sham programs interoperate seamlessly with Racket programs, and so no additional effort is required to use a DSL implemented with Sham. Finally, Sham comes with a framework for defining DSL compilers and transformations, which is also used in the implementation of Sham itself. We validate Sham's design on a series of case studies, ranging from Krishnamurthi's classic automata DSL to a sound synthesis DSL and a probabilistic programming language. All of these are existing DSLs where we replaced the backend using Sham, resulting in major performance gains.
READ FULL TEXT