martinfowler.com logo Home Blog Articles Books About Me Contact Me ThoughtWorks

DomainSpecificLanguage dsl 13 February 2004 Reactions

The basic idea of a domain specific language (DSL) is a computer language that's targeted to a particular kind of problem, rather than a general purpose language that's aimed at any kind of software problem. Domain specific languages have been talked about, and used for almost as long as computing has been done.

One community that uses DSLs a lot is the Unix community where they are often referred to as little languages or mini languages. (Eric Raymond provides a good discussion of this tradition.) The most common unix-style approach is to define a language syntax and then either use code generation to a general purpose language, or write an interpreter for the DSL. Unix has many tools that make this easier. I use the term External DSL to refer to this kind of DSL. XML configuration files are another common form of External DSL.

The lisp and smalltalk communities also have a strong tradition of DSLs, but they tend to do it another way. Rather than define a new language, they morph the general purpose language into the DSL. (Paul Graham describes this well in Programming Bottom-Up.) This Internal DSL (also referred to as an embedded DSL) uses the constructs of the programming language itself to define to DSL. This is a common way to work in any language, I've always thought of defining functions in such a way to provide a form of DSL for my problem. But lispers and smalltalkers often take this much further. Another term for an API written in this style is FluentInterface.

I have an extended example of both kinds of DSL in my recent paper on Language Workbenches. I also talk a lot more about the pros and cons of the two styles and the recent development of language workbench tools in the hope of making DSLs become more widespread.

One of the tricky aspects of DSLs is that it can be difficult to say what is and isn't a DSL. There is a very fuzzy DslBoundary between internal DSLs and APIs; and between external DSLs and general purpose programming languages.

I keep a note of DSL-oriented articles that appeal to me at DslReadings.

Choosing Between Internal and External

The internal and external streams come to an interesting confluence in the figure of PragDave. The pragmatic programmers have long been fans of DSLs, primarily from the Unix tradition (there is an excellent discussion in section 12 of The Pragmatic Programmer - perhaps I should call that Pragmaticum 12). In a thoughtful interview Dave said that while he regularly uses code generation, he rarely uses it programming in Ruby.

I've always used the analogy of creating a DSL to help think about building up a design - developing classes and methods with an eye to making them be a DSL. As much as possible I do this within the language I'm using, but if I can't I'm very ready to switch to code generation. At ThoughtWorks we've used code generation and similar techniques widely on our larger systems. The point at which I pull the separate language DSL lever is clearly different between languages. I never really felt the need in Smalltalk to use a separate language, while it's quite common in C++/Java/C#.

As a result it certainly seems to me that certain languages are more suited to internal DSL than others. Seeing lisp and smalltalk I concluded that the more suitable languages were minimalist ones with a single basic idea that's deeper and simpler than traditional languages (function application for lisp, objects and messages for smalltalk). But Ruby is more conventional and a much bigger language than these two, yet is still suitable for internal DSLs.

So perhaps it's that languages need to have a well chosen terseness. They need to make it easy to say common things and give you nice syntax to avoid complex twists. Whatever it is I think there's something very important here. I often find it hard to put into words why it is I enjoy programming in Smalltalk or Ruby so much more than in Java or C#. The most talked about reason is static versus dynamic typing, but I've always felt that that discussion misses the point. The friendliness towards internal DSLs is much closer to the essence of the difference.


Links
home
bliki
feed 
Translations
Japanese
Spanish
Korean
Chinese
Thai
Categories
agile
design
dsl
leisure
refactoring
ruby
thoughtWorks
tools
uml
writing
Blog Roll
ThoughtBlogs
TW Alumni
Nicholas Carr
Steve Cook
Brian Foote
Simon Harris
Gregor Hohpe
/\ndy Hunt
Ralph Johnson
Patrick Logan
David Ing
Brian Marick
Jeremy Miller
Jimmy Nilsson
Samuel Pepys
Keith Ray
Johanna Rothman
Kathy Sierra
Dave Thomas

© Copyright Martin Fowler, all rights reserved