Earlier, I covered a language design pattern that I called Escape hatch: giving your users a way out of their domain-specific language into a more powerful one.
Niko Stotz has written in to tell me about a special form of escape hatch that he has implemented on a project that he was working on. Here is what he wrote:
When reading about escape hatch, I thought about another use case: We build a DSL to replace an existing code base in a lower-level language (brownfield project). We obviously want to raise the level of abstraction, so we build nice high-level concepts. But that gets us only up to a point; a few existing constructs cannot be represented. Then we can either “pollute” our DSL with weird concepts, or use the escape hatch to fall back to the existing low-level implementation in these cases. In this scenario, we don’t allow users to create new instances of our escape hatch – they can only be used to represent old, possibly imported, code.
I consider this “constrainted” escape hatch an interesting compromise between building a fully functional escape hatch that would give your users a lot of power but could potentially lead to them writing low level code that would be difficult to maintain or port to a different target platform, and no escape hatch at all which would help stay technology-independent at the expense of missing power.
Niko wrote more about the DSL he built in Migrating Insurance Calculation Rule Descriptions from Word to MPS (a chapter of the book Domain-Specific Languages in Practice with JetBrains MPS)