Making your life easier with domain-specific languages (DSLs)

Igor R. Alves
WAES
Published in
6 min readJan 26, 2023

In the world of domain engineering, if you use the same language for many purposes or maybe across multiple domains, then you probably are using a general-purpose language (GPL). One good example is Java which, like many others, can be applied to solve almost all software necessities we can face. Almost.

GPLs can be as wide as our planet! Where is the problem?

General-purpose languages

First of all, let’s figure out some business needs where the GPLs are nicely applicable. For example:

  • Applying a customer discount on your favorite store
  • Validating important fields in your documents
  • Calculate how much time a rocket needs to arrive on Mars, Jupiter…
  • Integrate with different systems inside a field (health, finances, logistics, government)
  • Create a mobile game like those you may be very addicted to and should take a break from

OK, I think it is enough to say how broadly we can go just by using one general-purpose language. Let’s move on.

The problem with general-purpose languages

Although GPLs are powerful languages, they have weaknesses like everything. We can even compare GPLs with general doctors:

They are good at solving the first layer of diseases (problems), but they can’t go deep, such as having a full diagnosis of heart disease (domain-related problems).

Deep subjects are not precisely reachable by general-purpose languages because they demand a facilitator particular to the domain, which means these original languages were not created to solve specific problems efficiently.

When these problems fall from the sky, engineers can produce thousands of processual code lines to solve them.

Try to imagine many interoperability steps and unaccountable conditions within your application structure to fix what was needed once for the domain. It can be a big problem for you and your team.

Imagine that later, the business requires a new feature to be implemented. You would probably spend a lot of time and effort doing it. First, to understand what is happening and, finally, to be able to update it.

Photo by Kristin Snippe on Unsplash

A different paradigm

Well, you may think that the problem itself will depend on the affinity of someone with the code or the code structure itself. Still, your project maintenance becomes a big problem. Other engineers see this part of the code as something to avoid. We are finally in a place where all the mentioned problems should be solved with a different paradigm: the language-oriented paradigm (LOP).

The language-oriented paradigm considers “language” as a software building block (like objects, for-loops, and other components). It consists of creating another language within the GPL structure. A “mini-language” and using this new element to solve a determined problem.

This specific language is actually called DSL, which stands for domain-specific language.

Domain-specific languages

The DSLs are created to solve necessities inside a domain. They are the contrast to GPLs, which is why they are a key part of domain engineering.

To be suitable to the domain, you can choose either to use an existing DSL or create a new one as long as it expresses the particular aspect, which may be the specific problem or the representation technique under the domain.

There are two types of DSLs:

  • Externals — which have their own interpreter or compiler;
  • Internals — that are implemented within a host language as libraries or other code structures since it is being exploited from a parent GPL.

Some examples of external DSLs are CSS3, Puppet, SQL, and Gherkin. On the other hand, good examples of existing internal DSLs are Mockito, Vavr, jQuery selectors, and JSX (from React).

When to use or create a DSL?

New DSLs must be well-designed to serve the proposal they are born for, or you will probably face more issues and risks than actual rewards. For this reason, here are some good tips to know when to use a DSL or to create one:

Domain-specific languages are less comprehensive.

If you are using or creating a DSL, getting over multiple domains is not a good idea, even if it is technically possible. DSLs are created to solve problems within one specific domain. So, you must limit them to their domain. If you are thinking of using or creating a DSL and it is englobing multiple domains, the DSL is probably not a good idea.

They should have minimal redundancy.

If there is too much redundancy within the language or with the general-purpose language, that is a bad sign. Redundancy directly influences code readability, which is fundamental to understanding the domain. So, if you see this in the DSL, perhaps it would not be the best solution.

Is there a real domain problem?

Maybe, the best mental exercise is to answer this question. Identifying whether the issue can happen on multiple aspects and on different occasions, or then it is just an isolated case that you can solve by using only a general-purpose language.

The risks

The first risk is related to time and effort. Adding a DSL to your project will increase its complexity and, consequently, its maintenance. Requiring more time and effort. This can compromise your sprint goal or even project if it is not well planned.

Also, if you plan to create one, things can get even more complicated. You may spend a lot of time creating it and polishing the DSL. Demanding too much effort to solve one specific problem in the domain. If not well thought out, you will spend more time with the DSL than solving the issues you first encountered.

Besides demanding time and effort, there is also another risk related to adaptation. DSLs can be complicated. They are related to a domain your team may not understand very well. So, the team will probably need to provide training sessions and document even more than expected. Having new engineers prepared to support the project will take longer, making your life harder.

Making your life easier

If you create your own DSL or even use an existing one, then your code must become more efficient. The brand-new language should help you eliminate the grunt and repetitive work.

The DSL needs to help you achieve clear thinking!

Because it splits the essential from incidental complexity, you will only care about validation at the domain level. If the language is well expressed in the idiom together with a “limited domain” abstraction, even business analysts can understand the problem and validate the flow from the code.

It can also help shift these business analysts to a deeper knowledge of the domain (even with less technical expertise). See, what a great thing!

Photo by Flipsnack on Unsplash

However, as I mentioned before, implementing a DSL involves risks, and it should follow the design goals not to create more problems. Many factors could exclude the DSL from your plans, such as the short delivery time and all the effort to design, implement and maintain responsibilities that could be out of sight.

Taking everything into account, having complex or inconsistent rules within the domain may lead you to need to implement DSLs into your project. It’s always good to check for a preexisting and stable DSL to avoid dealing with all the problems of creating your own. Still, if you don’t find one and decide to create by yourself, then good luck. If it gets well-built, it is all about success!

Do you think you have what it takes to be one of us?

At WAES, we are always looking for the best developers and data engineers to help Dutch companies succeed. If you are interested in becoming a part of our team and moving to The Netherlands, look at our open positions here.

WAES publication

Our content creators constantly create new articles about software development, lifestyle, and WAES. So make sure to follow us on Medium to learn more.

Also, make sure to follow us on our social media:
LinkedInInstagramTwitterYouTube

--

--

Igor R. Alves
WAES
Writer for

Brazilian Lead Engineer in the Netherlands with a passion for tech, philosophy, travel, and exploring cuisines.