A time for a DSL

time to read 2 min | 330 words

Most of the time, I use a DSL as a way to setup and configure some sort of a runtime engine. We will get to that later when we will talk about imperative vs. declarative DSL. But the rule of the thumb that I use is that I’ll use a Fluent Interface if I usually need this functionality at the same time I am developing.

If I need to be expressive at a different time than the development of the application, then it probably means that I should use a DSL instead. The issues of complexity vs. expressiveness also come into play, of course.

If I can have a more expressive syntax out of a DSL than I can when using a Fluent Interface, that is also a consideration.

I’ll admit that I tend to favor building DSL over Fluent Interfaces, precisely because I leant the other way in the past, and got burned badly by the complexity involved in trying to maintain something of that complexity in a rigid language.

If you need to do things externally, a DSL is the place to look for. In fact, if you feel the urge to put XML into place, as anything except strict data storage mechanism, that is a place to go with a DSL.

Fluent Interfaces relies heavily on intellisense in order to create that fluent feeling. If you need to work on it outside the IDE, that is probably going to be a factor.

Extensibility is also a concern; let us go back to the scheduling sample. We have the scheduling engine, and we have the tasks themselves. Consider that to write a task using a DSL I usually have to write a small text file, but to write a task using a Fluent Interface requires creating a project, compiling, etc.

This means that it is often easier to use a DSL than a Fluent Interface, especially if we would like to hand this DSL to non developers.