Domain-Specific Language

Learn about domain-specific language with an example.


In the previous chapters, we learned the basic techniques and tools of functional programming and also explored the ways of using the power of monads. What we learned in those chapters is sufficient for writing a large variety of programs, but programmers have developed a few more advanced techniques that might be useful as well. The need to use these advanced techniques depends on the requirements and complexity of the projects. In the world of microservices or serverless, there’s a good chance any individual application (like a single Lambda) contains code ranging from hundreds to thousands of lines in length. If we work in that kind of environment, hiding implementation, folder organization, and intelligent naming are often sufficient for keeping our project understandable and usable.

We should proceed cautiously. It’s often been said that the book Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four brought in its wake not just better design, as the authors hoped, but also a lot of complexity. Some developers figured that they simply had to use design patterns wherever they could, instead of where appropriate. Similarly, tagless finals, free monads, and even DSLs help navigate certain specific issues or complexity and, at the same time, cause additional complexity.

Domain-specific languages

Most of our previous work was focused on a small set of principles for building applications. Those principles will probably sound familiar by now. Namely, we create small and preferably pure functions and combine them with composition or monads to form larger functionality. Repeat this process until we have an application.

When building our applications, we also paid some attention to modularisation. Because we don’t have classes to help with information hiding, we use modules, exposing only the functions that are really needed by other parts of the application. By minimizing the surface area of our modules, our code becomes more understandable to outsiders. Compare this to an application that exposes every possible function. While that would still be better than putting all our code in just one file (at least the names offer clues on where to find a relevant piece of code), it’s still quite bad. A developer looking at file A has to keep functions B, C, and D from files one, two, and three in mind when looking at our code. If those additional functions have a certain goal in common (say, handling authentication), it’s better to place them all together and expose them through a minimal API.

Get hands-on with 1200+ tech skills courses.