QCon 2008: Domain Specific Languages

Today was the first day of the conference and it started with a tutorial about DSL’s with Martin Fowler, Neal Ford and Rebecca Parsons. We also had as attendants Ola Bini, core developer of JRuby, and others. My expectations were pretty high and the presentation didn’t let me down. I’ll try to put here toghether my impressions and some notes I took while I was there.

Marting Fowler started discussing what DSL’s are and giving some examples that many of us use in our day to day Job. Like the XML configuration files in the Java world. It is a kind of DSL, it has it’s own keywords and syntax in order to express some information that will be used , for instance, to configure an underlying framework.

The problem with XML is that it becomes hard to see the overall behavior behind it. It’s not very fluent to understand the purpose of an XML file just by looking at it for the first time. There is too much “noise”. Things that get into the way of the readability. - YAML files are an much more readable alternatives to XML.

The same happens with a standard framework api code. Let’s take for instance a sample API configuration code written in Java to tackle the domain of hotel reservations. A framework like this could have the following implementation:


HotelService hotelService = new HotelService();
PersonService personService = new HotelService();


Hotel hotel = hotelService.findById(1);
Person guest = personService.findById(10) ;

Reservation reservation = new Reservation() ;
reservation.setFrom(“2008-03-10”) ;
reservation.setTo(“2008-03-14”);
reservation.setGuests(new Person[]{guest});

hotelService.book(hotel, reservation);
Of course implementations of this simple example may vary but we can see here some of the readability problems. One approach we could use for that is to develop a Fluent Interface to wrap this API. This was one of the techniques explored during the tutorial and the actual fluent interface could now look somewhat similar with this:


new Hotel(1)
.book()
.forGuests({
person.find(10)
})
.rooms(1)
.from("2008-03-10")
.to("2008-03-10");


Much more readable, huh? One of the main benefits of using DSL’s they highlighted in the tutorial is the simplicity of code you can achieve. You can actually show this code to a business person and he can understand it. This is a kind of internal DSL.

But there is still a bit of noise in this code. The the parenthesis which are not always desirable, and the use of double quotes for dates. But, this is Java code, and Java doesn’t give too much room for you on the DSL subject. Here was when the speakers changed their focus a bit to Ruby. It’s dynamic nature and metaprogramming techniques provides a powerful flexibility that allows for a looser syntax.

So in ruby the previous interface could look like this now:


Hotel.find(1) .book(1.room).forGuests {
Person.find(10)
}.from(march.10.2008).to(march.10.2008)


We got rid of the double quotes and the code looks more fluent, like a normal english sentence. I doubt a business guy woudn’t understand what this code is doing. With this, we can get closer to the business guys, with a common vocabulary, and fill the gap between us.

This is just one of the ways we could have written this code and is not the actual example used in the tutorial. The syntax also really depends on how readable you wanna make your code. I’ll provide those later when they release the digital format of the presentation.

So one of the flows that the development of an internal DSL can get is to build a framework and define the DSL on top of it. But we should also keep in mind that DSL’s shouldn’t be general purpose programming languages. They should be created to tackle a specific kind of domain problem, so we would have a whole system made of small DSL’s.

Another interesting subject that was touched is testing. How do you test DSL’s?
The suggested approach, and that I think is quite reasonable, is to have separate tests for the underlying framework and another to test the DSL and its parser you can assure you have the expected behaviour of both parts.

This is really just a summary of my thoughts and of what happened there. I’m not going into too much details right now but if you found something too abstract - and it is! ;) - feel free to ask details. I’ll be more than happy to help.

This is definetly an interesting subject and now I’ll head to play more with all that. :)

PS; This is not the whole presentation, just the best of it from my stand point. Other subjects include External DSL’s which can actually involve you coding Lexers, Parsers and Compilers. It’s usually not worth the hassle. And it’s too complicated anyway, that’s why I left it out from this post.

Comments