-
22 February 2010, 16:24
Internal vs. External DSL
A domain-specific language (DSL) is a programming language dedicated to a particular problem domain. One common application of a DSL is build tools. Any Java developer has at least heard of Apache Ant, an external DSL. Ant is external because its syntax is XML, but it is interpreted and executed by Java. Frankly, I don't like the idea of an external DSL.
Why don't I like external DSLs? Well, how do you do some one-off task?
Let's take Ant and the build paradigm for example. Maybe you want to ask a remote server for information. I've had to verify testing data against expected results on a remote server. Could you imagine trying to do that with XML? That is why I prefer internal DSLs. You have the full power of the language behind the DSL, as well as the domain-specific utilities. You don't have to drop out of your DSL to do one-off tasks.
I've played around a little with Rake (Ruby). It's nice, but, presently, I do a lot with the JVM. Buildr just didn't feel right. Now, I'm starting to learn Gradle. It's an internal DSL, built on Groovy. Groovy is a nice base, because everything that I have written in Java can be imported into my Groovy code. In Groovy, Ant tasks are "fist-class citizens", meaning that extensive Ant scripts are still usable!
With Gradle, I feel like I have so much more power in a more expressive--whatever that means--language. For example, how would you write:
with Ant? I realize that isn't too impressive, but what does that example mean? It means that we have loops. Build DSLs are dependency-based programming languages. One task depends on another. But with Gradle and Rake, we aren't limited to just that paradigm. The world in which we develop is still available to us when we build. Now, I've heard the argument that an internal DSL is more difficult for a non-developer. Granted. But who is righting your build scripts? Your business analysts?task count << { 4.times { println "$it " } }