• Types of Domain Specific Languages

    Domain Specific Languages are something that first appeared on my radar some time ago – I believe via Peter Bell’s excellent blog. I read a good amount on the subject at other websites as well including Martin Fowler’s DSL site. While the ideas were very interesting, they always seemed a bit “over my head”. But the idea of DSLs recently cropped back up when I decided to start tinkering with building my own application generator in ColdFusion.

    The nice thing about using a DSL with a application generator is that you can program all your app details in this DSL and then run a generator to expand your DSL code into a full application. And then, if you need to change the application later, you can simply change your DSL code and regenerate your application. It is basically a configuration file that defines part or all of your application.

    One difficult thing about getting started with making my own DSL though was there are very few good concrete examples of DSL use within ColdFusion. However, I identified three main categories of DSLs I was interested in – XML based, ColdFusion syntax based, and my own made up language not based on any other. Martin Fowler describes these concepts and internal DSLs and external DSLs. Internal are those that rely on a parent language (like ColdFusion, Java, Ruby, etc.) and its syntax. They usually just use a very small subset of the parent language. An external DSL is one which is one which is completely independent of any other language’s syntax. It can be completely “made up” by its creator and isn’t restricted to any of the rules of a parent language. I would highly recommend spending some time reading Fowlers website if you are interesting in learning more about this.

    The problem, as with many things, is getting started. I know I was a bit perplexed as to where to start. But, to help others that might be wondering about this topic and to get some feedback myself I thought it would be good to post a couple DSL examples that I’ve been playing with as I work on a ColdFusion code generator. All the examples present the same thing, but do so with different syntax.

    XML Based

    This first example is XML based. On one hand I do like that it would be fairly easy to parse and is well understood by many people. On the other hand it is very verbose. This example is based on an example that Peter Bell gave in one of his presentations.

    <entity name="user">
      <title>User</title>
      <properties>
        <property title="UserID" name="userID" column="user_id" dataType="integer" primaryKey="true" />
        <property title="UserName" name="username" column="username" dataType="string" maxLength="15" minLength="4" required="true" />
        <property title="Password" name="password" column="password" dataType="string" maxLength="50" minLength="8" required="true" />
      </properties>
    </entity>

    CFML Based

    Here is a version based on ColdFusion and it is accomplished using method chaining. One nice thing about this method is that there is no need to parse the code because ColdFusion takes care of that for you. It is simply methods chained together which ColdFusion executes and throws and error is there are any syntax problems. Like XML though, it can be very verbose.

    Entity('user').
      Title('User').
        Property('userID').title('UserID').column('user_id').dataType('integer').primaryKey(true).
        Property('username').title('UserName').column('username').dataType('string').maxLength(15).minLength(4).required(true).
        Property('password').title('Password').column('password').dataType('string').maxLength(50).minLength(8).required(true).
    end();

    External DSL

    This final version is not based on any other languages syntax. This allows for tremendous freedom to have full creative freedom to design the language however you like. However, you must be able to parse the language which means you’ll need to build a parser which can be quite difficult depending on the complexity of your language.

    Entity user
      Title="User"
      property name="userID" title="UserID" column="user_id" dataType="integer" primaryKey="true";
      property name="username" title="Username" column="username" dataType="string" maxLength="15" minLength="4" required="true";
      property name="password" title="Password" column="password" dataType="string" maxLength="50" minLength="4" required="true";
    end

    So what are your thoughts on these three DSLs? What are you using and why?