Friday, October 06, 2006

A categorization of DSLs

At this year's JAOO conference, I was the track host for the track called "DSLs and Beyond". It was planned that Martin Fowler would do the intro session, but he had problems with his back and he couldn't make it. So I had to prepare an alternative intro session. I decided I'd like to talk about categorizations of DSLs. So this blog post is basically what I came up with.

Domain Selection: If you talk about a Domain Specific Language, the first thing you need to do is to define the domain for which you want to build your DSL. In the context of software development it is useful to distinguish (at least) two kinds of domains: Technical Domains adress key technical issues related to software development such as Distribution, Failover and Load-Balancing, Persistence and Transactions, GUI Design or Concurreny and Realtime. Fuctional (or "Business") domains represent the business/professional issues; examples include Banking, Human resource management, Insurance, Engine Controllers or Astronomical Telescope Control. Some times these two kinds of domain are also called Horizontal and Vertical domains. You also have to decide whether you DSL should be rathergeneral to the domain you've selected or specific to your use cases in the domain; in other words, selecting a domain always implies tradeoffs between more general applicability of the DSL and more specificity (and thus, better support for your specific needs).

Expressive Power: The next issue you have to decide upon is whether your DSL should allow creative construction or use a metaphor that is more configuration like. Creative Construction means that the DSL defines a number of "words" from which you can creatively construct "sentences", the models. On the other hand, configuration languages typically allow you to select and unselect features that your system might or might not have - this selection can be as simple as three checkboxes or as sophisticated as a feature model. The two alternatives - creative construction and configuration - are in fact not alternatives, they are the two extremes on a continuum. Your DSL can be located anywhere on that continuum. In any case, you have to decide about the expressive power of the DSL and the freedom you want to give your users (a lot of freedom in case of creative construction, less freedom for configuration DSLs). Note that, of course, this issue is related to the domain. Certain domain lend themselves to configuration, others are better served by creative construction. In general, I think it is fair to say that the more mature a domain is, the more configuration-like the DSL to describe models in the domain will be.

Concrete Syntax:Yet another dimension along which DSLs can be structured is their concrete syntax. Graphical notations is what everybody talks about in MDA. However, textual notations are also very useful. You can even use tabular notations or some kind of custom-made forms (or GUI dialogs). Graphical notations are useful if you want to destribe structures or relationships between things (and also to impress prospective customers :-)). Textual notations are well suited for behavioral or algorithmic aspects (although state machines and petri nets kind of proof the opposite :-)). Typically, graphical, as well as textual modeling is a form of creative construction. For configuration DSLs, often tabular notations or specific GUI forms are well suited. Textual notations are also often useful. The amount of work you need to put into the construction of the editor is vastly different for these various alternatives. Building graphical editors is quite a bit of work (in spite of tools such as GMF!). Tools for building textual editors are starting to emerge (e.g. oAW's xText or INRIA's TCS and TGE). From my perspective, building textual editors (even with syntax hightlighting, constraint checks and code completion) will probably stay less complex than building graphical ones. The effort for builing GUI-based editors (incl. tree views and the like) is probably even lower ... and the editors are usually less pleasing and productive. There's one thing that has to be kept in mind: if you use textual editors, things like diff and merge is much easier. So the integration of the models (i.e. text files) with CVS etc. is much simpler compared to all kinds of other models (ever built a graphical diff for your GMF editor? Or tried to diff on the object structures directly?)

Execution: Another important aspect is the way the "program" is executed. There are two fundamental forms. One is transformation (also known as compilation), the other one is interpretation. Each of these approaches requires tradeoffs in respect to performance, code size, the ability to change stuff at runtime, reflection, etc. We all know about these tradeoffs from programming languages. There are also ways to combine the two: you can, for example, generate some XML document from a graphical representation of a state chart and then interpret this XML document. In general, it is easier to write a code generator (or any kind of transformer, for that matter) since you're dealing with more concrete things. There is another reason that can explain why transformation and code generation is the predominant form of executing DSLs (at least, external ones): if you have to run your system on a predefined infrastructure that requires certain artifacts to be present (such as J2EE, or many embedded OS) you have no choice but to generate these artifacts. Interpretations cannot help you there.

Internal vs. External: There's another aspect, and that is actually considered by many to be the most important distinguishing feature of DSLs: a DSL can either be separate from „normal“ programming languages or it can be embedded (in what is then often called the host language"). The premier language these days for embedding DSLs is Ruby (historically, Lisp was the champion there). To be able to embed a DSL into a language, the syntax of the host language must be flexible in order to "tweak" it a bit to suit the DSL. You'll always be limited by the kind of syntax the host language allows (tweaked or not) - that's the primary disadvantage of this approach: external DSLs are more flexible wrt. to syntax. However, internal DSLs have one big advantage: and that is symbolic integration (a term borrowed from Martin Fowler). this means that a symbol that is defined in the DSL part of the overall program can be used in the host language - and vice versa. Also, you can for example use the expression language of the host language in the DSL - very useful! Often internal DSLs are interpreted (as in Ruby, relying heavily on runtime meta programming). However, you can also use compile time metaprogramming to have a more static approach to embedded DSLs. Larie Tratt's converge language is an example here.

Tooling: So, these are the most important distinguishing characteristics of DSLs. There's another consideration. It's not a language characteristic, but it is important: tool support. Are there decent editors? Debuggers? What about refactoring support? You should also take these aspects into account when selecting a DSL approach.
Comments: Post a Comment

<< Home

back to

This is Markus Voelter's Blog. It is not intended as a replacement for my regular web site, but rather as a companion that contains ideas, thoughts and loose ends.

December 2005 / January 2006 / February 2006 / March 2006 / April 2006 / May 2006 / June 2006 / July 2006 / August 2006 / September 2006 / October 2006 / November 2006 / December 2006 / February 2007 / March 2007 / April 2007 / May 2007 / June 2007 / July 2007 / September 2007 / October 2007 / November 2007 / December 2007 / January 2008 / February 2008 / March 2008 / April 2008 / May 2008 / June 2008 / July 2008 / August 2008 / September 2008 / October 2008 / November 2008 / December 2008 / January 2009 / February 2009 / March 2009 / April 2009 / May 2009 / June 2009 / July 2009 / August 2009 / September 2009 / October 2009 / November 2009 / December 2009 / January 2010 / February 2010 / April 2010 / May 2010 / June 2010 / July 2010 / August 2010 / September 2010 / October 2010 / November 2010 / December 2010 / January 2011 / March 2011 / April 2011 / May 2011 / June 2011 / July 2011 / October 2011 / November 2011 / December 2011 / January 2012 / February 2012 / October 2012 / January 2013 /

You can get an atom feed for this blog.