Embedding a Domain Specific Language in TypeScript

Domain Specific Languages

Overview

A Domain Specific Language (abbreviated DSL) is a machine consumable language designed to clearly and succinctly express ideas for a single problem area (domain). DSLs are designed for subject matter expert consumption and authorship; those experts need not possess software development experience. Domain information encoded in a DSL can often be deployed independent of other software artifacts which reduces delivery friction. As such, a DSL can improve turnaround time, velocity, and increase staffing opportunities in the area of the business covered by the language.

DSLs can be text-based or visual where visual languages tend to be a better fit for low complexity requirements. Example DSLs include most video game logic, business oriented workflows languages (ex. Power Automate, Azure Logic Apps), many ETL systems, and even BI dashboards.

DSLs are a great fit when a business

  • Develops a product with logic / behavior describable by subject matter experts. 
  • Has a sufficient demand for such logic / behavior to justify the cost of both training subject matter experts to use the DSL and the upfront development of the DSL and related tooling. 

This article describes using TypeScript and related tooling to drive down the upfront cost of developing a DSL.

No Free Lunch

Building a completely custom text based language processor (interpreter or compiler) costs days to months based on language sophistication. Unfortunately, that is not the full story. In order for domain experts to effectively integrate a text-based DSL into their workflow they require complementary tools that cost additional weeks to months to years to build! Visual DSLs similarly cost weeks to years to get right, and they are deceptively difficult to design for user productivity!

Embedded Domain Specific Languages

An Embedded Domain Specific Language (EDSL) is a DSL embedded in another computer language such that the EDSL can leverage the processors, tools, and editors built for the host language. The upfront cost to develop an EDSL is therefore reduced by nearly an order of magnitude when compared with custom DSLs.

The drawback of an EDSL is that its design is constrained by the lexical representation and grammar of the target language. However, you may be surprised at how accessible a well designed EDSL can be for your domain experts (consult a book on EDSL design). As always, it is wise to run design experiments prior to investing too much in any sizable solution to ensure usability by your user personas.

TypeScript

Why A Good Candidate

Deployment and Integration

TypeScript provides numerous options to integrate proprietary business logic with the TypeScript language and tooling.

  • Author a TypeScript Playground Plugin and publish to NPM to integrate your custom code without the need to manage hosting and deployment. While publishing to NPM requires your code to be publicly visible, the plugin can be authored to interact with your business data via an authenticated service / back-end. 
  • If having your code publicly accessible is a problem then you can even host a proprietary version of the TypeScript Language Playground on your own protected servers.
  • For even greater integration, the Monaco Editor, TypeScript Language Service, and TypeScript compiler can be integrated directly into your own web client (SPA)! The tools are open sourced on GitHub with permissive MIT and Apache 2.0 licenses (as of the time of this writing). This gives your EDSL all of the power of validation, code completion, hints, and the tremendous text editing capabilities integrated directly into your own, potentially branded, product.

Type System

TypeScript, as of version 4.1, has one of the most expressive type systems in use outside of academia. This incredible type system provides tools for EDSL designers to craft extremely safe and helpful interfaces for domain experts to inhabit.

The type system is able to

  • Compute entirely new types based upon literal values. This empowers a class of extremely safe and adaptive APIs ideally suited to domain specific languages as the type system can refine what is valid at a point in the code based upon code that has come before.
  • Perform numerous typing operations on string literals! This will blow your mind on first exposure and is extremely useful for EDSLs as string literals are often more comfortable for non-technical users.

Why Not

The TypeScript language includes a lot of unfriendly tokens (brackets, parentheses, quotes, and periods) which clutter the EDSL and can be difficult for non-technical users. This problem can be partially mitigated through careful EDSL design. Integrating a code formatter (such a Prettier, also open source) helps to avoid parenthesis matching confusion which can trip up authors technical and non-technical alike.

How

TypeScript can be used as the host language for an embedded domain specific language through the basic pattern

  • Work with domain experts to design an EDSL which solves a business problem with a complexity tolerable by the user group. In TypeScript, this design is likely to employ JSON literals or a fluent builder pattern.
  • Author a run-time which compiles to JavaScript such that the EDSL itself can be run to produce an artifact. This artifact may be simple data, an abstract syntax tree, instructions for a virtual machine, or executable JavaScript (latter discouraged for security reasons).
  • (Optional) Generate TypeScript type declarations for the EDSL dynamically based upon specific business context/data. Type declarations provide opportunities for both specific validation and user assistance in the form of code completion and documentation. The code generating the type declarations could be written in server language such as C#.

Example

As a very basic example you might try my TypeScript Playground Plugin for iteration planning which demonstrates simple two-way communication between a program and a TypeScript editor.

  1. Open TypeScript Playground
  2. On the right side of the screen select the Plugins tab.
  3. Scroll down the list of plugins to find "Planning Day". Place a check next to the Planning Day plugin.
  4. Refresh your browser tab
  5. You will observe that a "Planning Day" tab has been added to the right side of the Playground.

In Conclusion

I hope that this article has piqued your interest in the subject of domain specific languages, the TypeScript type system, and the open source TypeScript tooling and ecosystem. There is a lot here that may be new to you. DSLs suggest a different paradigm for delivering business value than traditional software development. On the technology side, the TypeScript type system can seem like magic. Further, the idea of incorporating a programming language and IDE into your software may seem like an extreme solution. It may be. My principal hope is that you keep this class of solution in the back of your mind when solving problems with software. I also hope you had fun.






To view or add a comment, sign in

More articles by John Suder

Others also viewed

Explore content categories