Thoughts on Martin Fowler’s Domain Specific Languages Overview

I’m way late in linking to this, but it’s worth it.

Last October, a presentation by Martin Fowler from JAOO 2006 popped up on InfoQ (which does a great job of simulating the actual experience of being at the session with its video/slideshow integration) where he gave a very high-level overview of domain specific languages (DSLs). He really only scratched the surface, but it’s a great introduction for those that haven’t yet thought about DSLs much.

(Of course, that population is getting smaller by the minute thanks to Ruby (and Rails), since it builds in the metaprogramming facilities necessary to implement internal DSLs.)

I recently had occasion to re-watch the presentation. This time around, I took the time to scribble down some thoughts:

    1. I think he played up the potential role of DSLs as “configuration code” too much. Yes, you can tailor a DSL to provide primarily configuration data, and that’s very useful as far as it goes. However, internal DSLs (given an appropriately useful host environment) are able to provide levels of abstraction and composability that go way beyond configuration.
    2. I think that casting the Java example he showed as a DSL is really over the top, and is a result of overemphasizing the potential configuration role DSLs can play. As Mr. Fowler said, the line between an internal DSL and just a bunch of specific goal-driven coding in the host language is fuzzy. However, a big part of that line (and therefore whether an environment can reasonably host a DSL) is how well the host language’s existing constructs can be recast as sensible constructs in the DSL. The Ruby DSL example fits this criterion well, as its range (4..12, etc) and block constructs mapped well to the domain at hand. On the other hand, the Java example is Java, unapologetically so — the explicit object creation, the function calls, return statements, etc., simply do not map to the domain. The fact that the integers and strings being passed in those function calls can be recast as an actual configuration file should not lead us to think that Java configuration code is a functional DSL.
    3. At least in my experience, external DSLs are dead-ends. There’s just too much heavy lifting that needs to be done to consume external DSL “source files” and align their contents with the host language’s environment. True, internal DSLs need to conform to the syntax of their host environment, but the advantages of “symbolic integration” (as Mr. Fowler puts it) and the fact that you get your IDE’s functionality for free are just too compelling to outweigh any nitpicky syntax quibbles that one might have with any DSL-capable language. And, if those syntax quibbles are significant enough, and the problem the DSL is going to solve is significant enough to make you come close to considering building all of the cruft necessary to implement an external DSL, then go find yourself a secondary language/environment that provides a more palatable syntax, and hook everything up with IPC of some kind.

    2 Responses to “Thoughts on Martin Fowler’s Domain Specific Languages Overview”

    1. Uri Shani Says:

      One notable statement you make about external DSLs is really incorrect, when looking at DSLs for the non-programmer, or the Domain (D in DSL) expert who need/should not be Java or other GPL literate. Here the advantages are huge in productivity and have important implications on system architecture and application design with well thought separation of responsibility between the framework programmer (GPL fluent) and the solution programmer (DSL author).

    2. Chas Emerick Says:

      Uri:

      I guess that’s why I prefaced that paragraph with “…in my experience…”. :-)

      As I said in point #2, I don’t think Java can host an internal DSL, simply because of its syntax. As for other general purpose languages hosting internal DSLs that are usable by non-programmers? I think that’s entirely doable, especially if the host language is something that permits one to define syntactic and semantic conventions that can be sensibly mapped onto the problem domain.

      But it sounds like you’re considering use cases where the “solution programmer” and the “framework programmer” are far apart — in a vendor/customer relationship perhaps. In that case, I can see how you would want to use an external DSL, as the customer would then not be able to muck things up badly by using the full utility of the language hosting an internal DSL.

      I’ve certainly witnessed such scenarios, but only in passing — in the domains I work in, DSLs are often (close to) a magic bullet for making the hardest programming tasks possible and maybe even manageable (which is what I was referring to in point #1). In these cases, there is still a proper “separation of responsibility”, but there’s no vendor/customer relationship — it’s usually more like an architect/junior programmer relationship.