Demystifying DSLs Part II : A Working Definition

Domain-specific Languages (DSLs) are everywhere, but there is precious little consensus on a working definition to describe them.

Academic conferences about DSLs turn to the presentation of ever more abstract tools aimed at simplifying the task of implementing DSLs, or the enumeration of more and more exotic application domains, together with the languages that have been designed to address them.

The papers from the latter are utterly enjoyable – a true benefit to the field if I ever saw one – but in terms of practical applicability they are essentially pointless as they merely document niche solutions to niche problems.

They don’t provide applicable wisdom.

They don’t give keys to recognize how your next problem might be best solved by a DSL.

And by the way, what is a DSL solution?

What is a DSL, for that matter?

To spare feelings, and avoid juvenile bickering consisting of, “my DSL is more of a DSL than your DSL”, some use ever more encompassing definitions to the point of irrelevance, where anything that aims at solving a particular problem for a particular domain qualifies as a DSL.

According to such a vague gospel, Make, Ant, and Excel are all DSLs, as they don’t solve universal problems. Squint hard enough, and HTML and emojis become DSLs too.

Pushing this inclusive logic to the extreme, some even go as far as claiming that DSLs don’t even have to be languages.  Class or function libraries qualify.

To quote a forgettable even if enjoyable piece of cinematic culture, “When everyone’s super, no one will be”.  Similarly, when everything is a DSL, nothing is. It becomes an undiscriminating definition devoid of any value.

Blurring the lines in this way does not help anyone, except for DSL taxonomists.  Like those looking for evidence of the golden ratio in architecture, nature, or even music, expanding the qualifying criteria gives these taxonomists even more DSLs to be excited about.

Many will disagree with my definition given in this post, but at least it is usefully discriminating.  It is based on two objective criteria that characterize recognizable situations, where equally recognizable solutions can be applied fruitfully.

First, a DSL is a language. It is not a mere library. The whole point is to consider that for a given problem, the benefits of a bespoke language offset the corresponding development and maintenance costs.

Full-fledged languages are very different from function or class libraries. They constrain developers into formalisms, enforce paradigms, and limit the number of concepts and features that can be used.

In certain cases, they can be used by people with extensive domain expertise, even if they are not technically savvy enough to start programming in a conventional third generation language, where issues such as types, persistence, exceptions, scopes, and other similarly important concepts must be mastered.

Changeability is the second and even more important characteristic of any DSL effort. Whoever uses it can decide to change it, alter it, and improve it. As a software engineer, going for a DSL means that one can tackle complexity at two levels, by designing the language to provide useful abstractions, and by using the language to exploit these abstractions– an extreme form of divide and conquer.

A situation where the language is a given, when its design will not budge, where its users have no say in how it evolves, is, in my opinion, not a DSL, or at least not a useful DSL.

Oddly enough, this definition does not even consider “domain-specificity” by itself as that much of a useful criterion, because domains come in all sizes and shapes.

Is business administration a domain? How about scientific computing or system programming?  Are they domains?

Depending on your answers, COBOL, Fortran, and C could arguably be domain-specific.

On the contrary, changeability requires closeness between the users and the development, making the DSL a local development, shared by a relatively small set of people with a common concern, not at all like the common understanding of the term “domain”.

More often than not, DSLs tend to be application-specific rather than truly domain-specific.

And this definition can be articulated as a possible strategy for complex software projects where we ask the question:

Can we define a fruitful set of abstractions encapsulated in a DSL to make the software significantly easier, faster, and more flexible to develop and maintain?