English as a DSL
“Programming is best regarded as the process of creating works of literature, which are meant to be read… so we ought to address them to people, not to machines.”
-Donald Knuth, Literate Programming
The last few days there has been a vibrant discussion on which computer science books that deserve its place on the top 10 bookshelf over at The Norwegian JUG. A title that quickly sprung to mind was Pragmatic Programmer: From Journeyman to Master by Dave Thomas and Andy Hunt. This is one of the few books that you can read from cover to cover, over and over again and pick up new things every time. Because I love this book, it feels a little scary to pick a discussion with one of the authors, but Dave’s latest blog post on domains specific languages provoked me to do this.
In his blog post, Dave makes the point that something isn’t necessarily a DSL just because it reads like English. I agree with him on this, but this does not imply that English can’t be used to describe business rules. In my talk on developing domain specific languages with .NET, I used an example from the insurance industry as a foundation for the alternative approaches for implementing a DSL. Insurance is a business I know well since I work for one of the largest insurance companies in the Nordic region. Just like Dave points out, our domain specialists have a common understanding of the meaning of the different terms in their jargon. In Domain Driven Design, Eric Evans describes this as the ubiquitous language. In my experience, having a shared understanding of the jargon between business and technical team members and using this jargon to model the software is crucial before on can introduce domain specific languages into the development process.
My example is a very narrow slice of the business rules for adjusting the risk of a car insurance quote. Still it is very representative for this kind of application. We begin our tale with a simple user story;

If we write our requirements in this manner, a natural progression is to write our functional tests in a behavior driven style.
Scenario(“Customer is an inexperienced driver”);
Given(“The policy’s premium is”, 1000, delegate(double premium)
{
policy = new Policy();
policy.Premium = premium;
});
Given(“The customer’s age is”, 24, delegate(int age)
{
policy.Holder = new Customer();
policy.Holder.Age = age;
});
When(“A quote for an insurance is issued”, delegate()
{
quote = policy.IssueQuote();
});
Then(“The policy’s premium should be increased by percentage”, 5, delegate(double percentage)
{
Assert.AreEqual(policy.Premium *= 1 + (5 / 100), quote.Premium);
});
This code is written using Joe Oscampo’s NUnit.Behave which I claim is an internal DSL, written in C#, for functional testing. Spec frameworks like NUnit.Behave is one of the things Dave “picks on” in his post with a valid argument that the domain experts using this DSL are programmers and that writing a specification using the such a framework is programming. This is true, but I think Dave misses a key value of using this approach; even if the specification is littered with C# enforced dots, brackets and parenthesis it is very similar to the free-form user story the spec is derived from. This helps us follow a thread through from the user story through to the specification. If the framework didn’t enforce a grammatical structure, this would be much harder to achieve.
Another thing with Dave’s problem with the host language shining through and hindering him in writing straight forward sentences can be turned into a benefit for fluent interfaces. Obie Fernadez once used the Starbucks jargon to show how to write an internal DSL with Ruby. I’ve used his example to show how one can implement a fluent interface with C#. This example is a variety of the specification pattern, and it is very helpful for object creation.
Imagine that you have a number of different coffee drinks such as espresso, latte and capuchino which all extend a common base class. There are different ways to prepare each of these drinks and hence you need to know what to put into them when you make them. Using traditional object oriented programming, you would first have to figure out which drinks are available by looking up the classes extending the Drink base class, and then you would need to identify the specific options for each drink by looking at its constructor overloads.
When using an internal DSL to create Drink instance, we can use the language to show the developer which options are available and since almost every IDE has some form of IntelliSense, these options will be very visible to the developer.

The value of using this approach is that it is much more readable than regular code and it gives the users (who are developers) an expressive API. Another thing Dave complains about is the use of noise words, like articles, in such DSLs. In this one I’m using the indefinite article “a”. The only reason this is there is that it serves as a starting point for out sentence, and I agree with Dave that there is no real reason to allow users to insert words like “a” or “the” in the middle of a “sentence” to make it feel more like proper English. Still I’m obsessed with aesthetics and if an definite article was the only thing missing before an API look perfect, I’d probably add it just to make it look better.
Allowing noise words in the language brings us to the extreme variety the DSL implementations I show during the talk - the plain English business rule. When use use user stories for our requirements and behavior driven development for testing, why can’t we just state our business rules like this:
When the policy holder's age is less than 25, increase the policy's premium by 5%.
This is code and it is compiled using Microsoft’s Dynamic Language Runtime and runs on the CLR. On thing to note is that this language is very specific, and has a limited set of operations. There is no way you can write “Hello World” with this language. Mandating a strict, limited grammar is a way to work around the ambiguities of natural language. Of course we can’t be too strict, so we’ll also have to allow things like:
When the policy's exposure has a burglar alarm, decrease the policy's selfrisk by 200.
If we translate this to plain old C#, we’ll end up with this:
// First example...
if (policy.holder.age < 25)
{
policy.premium *= 1.05;
}
// Second...
if (policy.exposure.has("a burglar alarm"))
{
policy.selfrisk -= 200;
}
“When” is a keyword, “the policy holder’s age” is a reference, “is less than” is an operator, “25” is a constant and so forth. All that is required is to parse it, emit and AST for the DLR and run it. Nothing is different from how general purpose languages work, which isn’t strange because even if these are true English sentences, writing them is programming.
The great thing about having things that are as readable as these code snippets is that it makes it easier to sit down with domain experts and use actual, running code as the basis for discussion. That said, I’m fully agree that the use of English doesn’t make things a DSL. Focusing on the domain model and developing a language that only takes into account the problems within that domain however does. If it makes sense to model your language around English language constructs, do it! This will make it easier for both developers and business people to understand business related code.
It takes a lot of effort to roll your own language as shown above, so from an economical perspective, you are better of piggybacking on another language. The Boo based variety of the same example looks like this.
when policy.holder.age < 25:
increasePremiumByPercentage 5
It might be broken English, but it serves its purpose and it is most definitely a DSL.