First, let me define a Domain Specific Language (DSL). A DSL as a small programming language specifically designed to communicate solutions for a particular domain of problems.
To expand on this definition, while the discussion of DSLs can include internal DSLs, which are implemented directly within a General Programming Language (GPL) using the available language constructs, I’ll primarily be focusing on external DSLs, which require a custom parser and provide the most flexibility in terms of design. That said, many of the points below apply to internal DSLs, too.
Now that I’ve described what a DSL is, let me tell you why I wish we used DSLs more.
DSLs Are Small
Today we have access to many wonderful GPLs. There are so many, in fact, that it’s sometimes hard to get teams to come together and choose the “right” language for a particular job.
Perhaps due to this perceived competition amongst the languages, it sometimes feels like we’re in the middle of a language construct race.
Programmer 1: “Language X can do this in a few keystrokes with one operator.”
Programmer 2: “Whatever, Language Y has the deathstar operator, which blows Language X out of the sky.”
Programmer 3: “Language Y? That’s so YYYY – 1. We should use Language Z. With it’s first major release (9 minor versions from now some unknown time in the future), it will provide all of the features of Language X AND Language Y.”
As GPLs add language constructs to “simplify” the work of programmers, they require more and more language-level expertise. Indeed, syntactically complex GPLs limit the number of individuals who can properly communicate solutions.
In contrast, well-designed DSLs increase the population of individuals who can properly communicate solutions. This inclusion of potential problem-solvers is one of their biggest strengths.
DSLs Are Specifically Designed to Communicate Solutions
Davin Granroth has told me of a professor during his college days who used to say, “Less isn’t more, just enough is more.” I see DSLs as tools that facilitate achieving this ideal through intentionally crafted parsimony.
In a well-crafted DSL, syntax is no longer a vestige of the GPL. Rather, every component of the grammar reflects careful choices that best facilitate the communication of solutions for its specific domain of problems, meaning the relevant information for a particular solution is brought to the surface. These qualities do lead to code that is easier to write. More importantly, these qualities also lead to code that is easier read, whether this happens hours, weeks, or years after the initial commit.
Additionally, because DSLs are focused on communicating solutions, they provide a great amount of flexibility when it comes to the actual implementation. Did the APIs change as part of the most recent service upgrade? No problem, the solutions communicated in the DSL don’t have to change. Do your programmers want to switch to language NextCoolRage? No problem, the solutions communicated in the DSL don’t have to change.
DSLs Adapt to Evolving Problem Spaces
“Work on this one specific problem, and I won’t change the constraints at all in the future…”, said no Project Manager (PM) ever. The solutions we communicate today may not adequately address problems we face tomorrow. Any tools we use to communicate solutions must provide the ability to easily accommodate change.
Because of their small size and specific focus on a particular domain of problems, DSLs can be created/adapted relatively quickly. Small languages can be implemented using relatively simple parsers, and making updates to the language is usually a straight-forward task. Additionally, because the problem space is so focused, the design and testing of changes is easier when compared to augmenting GPLs.
When your PM speaks of unanticipated changes that have to be addressed in the next sprint, you can nod your head and smile, retreat to your whiteboard, and start adapting/creating the DSLs that will allow your domain experts to properly communicate solutions.