Software development, like any other industry, has trends. Over the past couple of years it's been fun to watch the ascendance of the Domain Specific Language meme. I’ve loved language design since I first started programming and I like to see people work in that design space. Language design is challenging and immensely satisfying work. It's been said that one of the oddities of software design is that we suffer from a lack of constraints. At times, we have severe memory or time constraints, but for the most part, there is nothing that forces us to choose, say, one object structure over another other than our understanding of how it might impact future change. When you design an embedded DSL -- a DSL built of constructs in a surrounding programming language, the structure of your classes has an immediate impact on the expressivity of your language. It's API development writ large.
But, embedded DSLs are just one part of the DSL space. The rest of the space is occupied by external DSLs -- standalone languages that compile down to some other language or a run-time. In general, they give you a freer hand. You can create a complete syntax and tune it directly to a particular domain. Most of your constraints evaporate. It’s a very tempting approach but it does have some pitfalls. When you are a consultant, you end up seeing many proprietary technologies that you can’t talk about. There are more external DSLs out there than most people realize and more often than not, I see companies trying to get rid of them.
Why?
Well, there are a couple of reasons. One is the cost of maintenance. Someone in the organization needs to know enough about the DSL to make the inevitable changes. In a way, this isn’t much different from the cost of maintaining a framework, but many organizations see it as a difference in kind because the tools that you use in an DSL implementation are often not the same as the tools that you use in conventional business applications. It’s one thing to hire developers who know C# or Java or Ruby and yet another to hire or make sure that you have some who know ANTLR or YACC. In some companies this is absolutely no problem. They hire very knowledgable developers as a matter of course and they are sufficiently polyglot to make the cost of maintaining a language implementation negligible, but on the other hand, there are many companies that look at the cost side. They write software, but their business isn’t software, so they are constantly trading off the cost of maintaining their DSL with the cost of dedicating those people to work that is closer to the business line.
One other reason why companies move away from external DSLs is that they can complicate hiring. Years ago, I designed an external DSL for an organization that felt that they could save money by developing a high level language that their domain experts could use directly. I spent a good amount of time on the implementation and it was used successfully for long time. After a while, however, they dropped it. The domain experts were technical enough to use a mainstream programming language, but beyond that, moving away from the DSL made it easier to hire them. Let’s face it, if you are looking for a job what do you want to have on your resume? A language used by precisely one company or one that is known or used throughout the industry?
Like the cost of maintenance, hiring cost is just one piece of the total cost of ownership for a DSL but it can be the one which tips a decision. One very public example is Erlang. People are paying a lot of attention to Erlang today, but we shouldn’t forget that it was dropped by Ericsson in part because they were concerned with their ability to hire and train developers. Many people know the story of Erlang, but what they don’t realize is just how common this scenario has been in the industry. I get to see a lot of legacy code in my work, and a good amount of it is in homegrown languages that companies have trouble supporting.
The thing to remember about DSLs is that they are a commitment and the commitment doesn’t end when the initial implementation is done. This is definitely true for external DSLs, but it’s also true for embedded DSLs, albeit at much smaller scale. When you make a commitment, you have to make sure that you have the will to follow through and you also have to make a sober assessment about whether you will keep the commitment even under adverse business conditions. If you can, it’s worth doing. DSLs are powerful technology.
Enough about failure. How can you succeed with DSLs?
Here are a couple of ideas:
- If you are creating an external DSL, consider open sourcing it or, at least, consider forming some sort of an industry group around it. This partially externalizes the cost of maintenance and avoids hiring trouble.
- If you can’t or won’t open your DSL(s) to the outside world, make sure that your developers are not expected to use them exclusively. If you don’t, you can expect to pay higher wages for developers of equivalent skill than you would otherwise. In negotiations, they will factor in the cost of working with little known technologies.
- Consider embedded DSLs as an alternative. Often they are easy to construct and they can give you many of the same advantages. Dynamic languages like Ruby are ideal for embedded DSL construction, but embedded DSLs have been written in just about every mainstream programming language.
I like external DSLs and I think we'll see more of them. But remember, success is a function of far more than the technology.
Yes! Like any breadwinner of the family, keeping the resume in mind is a must.
"In negotiations, they will factor in the cost of working with little known technologies."
True. I tried that once with the technology WebObjects (Apple.com). The manager didn't bite. The company closed the office anyway. It made my life a little harder trying to find a job. In interviews, I kept having to explain what WebObjects is.
Links to "embedded DSL" good practices would be great. Anyone?
"Dynamic languages like Ruby are ideal for embedded DSL construction..." That's good to know.
From what I have seen, Ruby is a little known/used language. Sure it made the list at TIOBE http://tinyurl.com/3xutoh
I give it the appropriate amount of time, but not as much as I would like.
IMHO, "embedded DSLs" need their own letters, eDSL or IDSL for Internal Domain Specific Language
Great post!
Posted by: Michael Finney | November 28, 2008 at 09:57 AM
I remember going to a workshop on DSLs nearly 10 years ago. One point that many people raised is that successful DSLs should be small and focussed. They should do just one thing really well, which makes them easy to pick up and does not tempt anyone into treating them as full programming languages.
For internal DSLs, I guess we have to wait for the return of Lisp, or hope that a language like Fortress (which has extensibility as a goal) eventually makes it :)
Posted by: Steve Freeman | November 28, 2008 at 03:14 PM
"If you are creating an external DSL, consider open sourcing it"
Right on. The explosion in open source is not due to altruism, but becuase it makes good business sense. Just look at Erlang. Ericsson dropped Erlang for a number of reasons, and it would have died a brutal, horrible death if it wasn't open sourced.
Companies invest in DSLs because they need to solve specific problems in a domain. What most of them fail to realize is that opensourcing a language is much more of a benefit then the potential loss in proprietary technology to a competitor. Repeatedly we see the strongest growth in technologies coming from de-facto standards due to wide use, rather than industry consortium attempts. Opensource also provides customers with a behind the scenes look at the talent of employess at a particular company and may infact have a direct impact on company valuation. Furthermore, if the technology becomes widely used it drives more developers to want to work for the company rather than shirking away because they won't be able to use the DSL on their resume.
I guess my point is: Don't be afraid of opensource.
Posted by: Andrew Stone | November 28, 2008 at 04:08 PM
External DSL's also have one particular issue with them, and that is that the grammar is completely left to the designer, and often times, some of the "good housekeeping practices" we abide by in more formal languages are tossed for the sake of expediency.
When there is no formalism behind how the syntaxis of a language, and the semantics of that syntax are expressed and the flexibility they provide to your end user, you end up with an "exception is the rule" language to fit the circumstance, and that as you've deftly pointed out is where you end up with these "niche skills". What you can best walk away with from a circumstance where you've worked with an external DSL is to learn from it's limitations. Remember "what NOT to do" when designing/implementing such a construct as the basis of a product.
Posted by: Marcelo Lopez | November 29, 2008 at 07:01 AM
The pain point with custom DSLs is in the debugging, and extending. Embedding interpreters is pragmatic, but might not suit a DSL which is more declarative than imperative.
Posted by: Chui Tey | December 01, 2008 at 07:51 PM
"If you are creating an external DSL, ..."
DON'T!
Too many people who thinks they are competant programmers, make the mistake of thinking that just because they can program a new language, they should.
But its more like the difference in being able to write, and being a successful novelist.
- Paddy.
Posted by: Paddy3118 | December 02, 2008 at 03:01 AM
Is there a book or scientific research papers out there with design patterns or other guidance on external DSL design?
I mean it's easy to bash bad external DSL designs but it is unfair to demand good ones if nobody ever observed them systematically.
Posted by: Sebastian Kübeck | December 07, 2008 at 07:13 AM
"Is there a book or scientific research papers out there with design patterns or other guidance on external DSL design?"
There's a great scientific article on this topic:
Mernik, M.; Heering, J. & Sloane, A. M. When and how to develop domain-specific languages ACM Comput. Surv., ACM, 2005, 37, 316-344
Posted by: Johan den Haan | December 10, 2008 at 06:09 AM
Thanks for the info! I withdraw my last comment.
Posted by: Sebastian Kübeck | December 17, 2008 at 11:15 AM
Fully agreed.
"External" DSL's really almost always suck.
Language design is intrinsically hard stuff.
With expressive languages that have support for closures and other advanced features, internal DSL's are really powerful enough.
And their other main advantage is that you don't need to implement all the infrastructure around the language again.
You not only need a compiler, you also want an IDE, a debugger, a code coverage tool etc.
Posted by: Markus Kohler | January 22, 2009 at 01:23 PM
Hi Michael,
It seemed that you at least have two blog. I want to see your "10 must read papers", but it seemed that your other blog is not accessible here in China (Hangzhou, where you used to work together with us).
Can you also put it here, or what's the problem with the other one?
Trying to contact you via twitter, but you are not following me:-) I'm terryyin.
br, Terry
Posted by: TerryYin | February 27, 2009 at 04:57 AM
>> Trying to contact you via twitter, but you are not following me:-)
+1, I'm amoswenger on Twitter =)
Posted by: Amos Wenger | July 27, 2009 at 09:34 AM
@Sebastian Kübeck: "Is there a book or scientific research papers out there with design patterns or other guidance on external DSL design?"
You're right that there's too little out there that is based on actual experience. At MetaCase we've been building external DSLs for over 15 years, both for and with our customers, and wanted to do our bit to improve the situation. I've written a book with Juha-Pekka Tolvanen, explaining about Domain-Specific Modeling and how to create your DSLs, build tool support for them, deploy them, and maintain them:
- Domain-Specific Modeling: Enabling Full Code Generation, Wiley 2008
http://dsmbook.com/
and recently with Risto Pohjonen an article that sounds similar in title to Michael's post, but goes somewhat further in providing actual advice on "how to fail":
- Worst Practices for Domain-Specific Modeling, IEEE Software, July/Aug 2009
http://www.metacase.com/papers/WorstPracticesForDomain-SpecificModeling.html
Posted by: Steven Kelly | October 12, 2009 at 01:28 AM