PragDave Nearly Gets Internal DSLs Right

chromatic on 2008-03-11T22:31:41

... let's look at it from a DSL point of view. What is the domain? I'm thinking it is the specification of the correct behavior of programs. And who are the domain experts? That's a trickier question to answer. In an ideal world, it would be the business users. But, the reality is that if the business users had the time, patience, an inclination to write things at this level, they wouldn't need programmers. Don't kid yourselves—writing these specs is programming, and the domain experts are programmers.

Pragmatic Dave Thomas, The 'Language' in Domain-Specific Language Doesn't Mean English (or French, or Japanese, or ...)

So very close.

The reason the so-called DSLs that Dave mentions are inaccessible to non-programmers is that they're merely Ruby APIs with poor encapsulation. People who do not know how to program Ruby code will have a difficult time reading and writing them. This is not exactly a feature, if you want business experts reviewing your executable specifications.

I'm sure they love looking at RSpec output and saying "Right there, it says the Wooble does not have a built-in Flimflam, that's the problem right there! Just fix that!" By the time RSpec spits out that helpful notice, it's already detected the problem. Useless, except that making RSpec actually useful to business experts requires something more than slapping the colon in front of random Ruby identifiers.

(ObContraDanielBerger: slapping the fat comma operator between indirect object invocations in Perl produces code that's just as bad and just as much not a DSL. The Perl community doesn't have this particular fetish to the same degree as the Ruby community though. Happy?)

Ever since programmers at large stopped having to cram their meaningful identifiers into eight characters (a feature planned for GHC 12.2, I believe), we've been able to subsume the language of the problem domain into our APIs.

Dave continues:

When you're writing logic like this, with exception handling, command sequencing, and (in more advanced examples) conditionals and loops, then what you're doing is programming.

This, more than anything, I think is the real dividing point between a DSL and an API. Here's my postulate for the day: a real DSL (make, procmail, SQL, regular expressions, FIT) is purely declarative.

I realize that Prolog might be a DSL under that definition, as might class declaration in Ruby (and ActiveRecord), but I can live with this as a first-order differentiator.


Counter-example

Alias on 2008-03-12T05:48:59

For a great example of a DSL that doesn't follow your "only declarative" rule is VoiceXML, which is absolutely a DSL.

If contains a sort of odd mix of declarative structures, mixed in with bits and pieces of logic ...

While I personally HATE this whole "XML as code" idea, in VoiceXML it works wonderfully.

Go read up on it, any study of DSLs is incomplete in my opinion without understanding VoiceXML.

Re:Counter-example

chromatic on 2008-03-12T06:07:32

For a great example of a DSL that doesn't follow your "only declarative" rule is VoiceXML, which is absolutely a DSL.

Good point.

"Purely declarative" is a red herring. The question is whether the language is general purpose or domain specific. Ruby (and Ruby APIs) are general purpose. That's sort of the point of a general purpose language: to allow you to write domain specific APIs. (Thank The DHH that his followers delivered us from such mundanity.)

In the same way, XML exists as a tool to describe domain specific documents.

Yes... mostly

pdcawley on 2008-03-12T14:28:34

I'm not sure that procmail's entirely declarative either, given that you can embed shell scripts within it (but then, I guess, those bits are no longer domain specific in quite the same way - as far as procmail is concerned they're data...)

I still maintain that there are real DSLs that can be written and embedded within a general purpose language (regular expressions being the canonical example). Damian Conway's List::Maker is an example that uses a parser, but something like Object::Declare is, I'd argue, a full on DSL that works by finessing the perl parser and its runtime structure without having to introduce a new parser.

Personally, I think RSpec's specify/describe stuff for specifying tests is as near to being a DSL as makes no difference, but the .should == "foo" stuff is just a clever set of classes and methods. But, that's a mighty big 'just'.

All that said, I still don't really see the value of making fine distinctions about what is and isn't a DSL. The only question that needs to be asked is "Does it work?". I simply couldn't care less about what you want to call it (or even, in the case of RSpec, what claims you make about it).

I take the view that programming is language design. The second you take a bunch of code, and give it a name so you can call it later, you're designing a language (admittedly, it's one that looks _very_ like the language you're implementing it in). The languages I like are those that blur the boundaries between the language and its libraries.

Hmm... comment in danger of turning into a blog post... I'll stop here.

Re:Yes… mostly

Aristotle on 2008-03-12T15:45:47

I agree that you can use a flexible host language to write things that have a different feel from just a plain API, and that one might reasonably call those DSLs, and that making too fine a point about distinguishing the two isn’t a very productive use of time. But there’s a lot of hot air from parts of the Ruby camp about how that language has the DSL market cornered, without any objective criteria forthcoming about what other languages lack in that department. And I agree with chromatic that a lot of what these people point at really aren’t DSLs (just idiomatic Ruby APIs).

Re:Yes… mostly

pdcawley on 2008-03-12T18:22:51

Well, yes. But idiots will be idiots and there's not a great deal we can do about it. I just worry for chromatic's blood pressure and wonder if he's indulging in pig wrestling.

Re:Yes… mostly

chromatic on 2008-03-12T20:41:28

I just worry for chromatic's blood pressure....

It's actually on the healthy side of low.

... and wonder if he's indulging in pig wrestling.

What's the Internet for if not pig wrestling over technical minutiae and fanfic?

Re:Yes… mostly

pdcawley on 2008-03-12T23:48:35

This is important... someone is wrong on the internet.

Thank you xkcd

Re:Yes... mostly

chromatic on 2008-03-12T18:56:55

All that said, I still don't really see the value of making fine distinctions about what is and isn't a DSL.

The concerns of language design and the concerns of API design overlap, but not fully. Syntax considerations matter far more in language design. This is why certain Rails APIs have stupid little do-nothing-but-forward-messages methods such as #a and #the.

I worry that the focus on creating these APIs produces unmaintainable messes of code. There's little chance that a business user who doesn't know Ruby is going to write code (or read it and understand all of its nuances correctly). Ruby syntax -- especially parser corner cases tied to particular implementations -- keeps leaking through.

As well, that syntax and the contortions required to make something look like English doesn't help Ruby programmers either. Ruby has a fairly nice syntax with blocks and methods (barring the proc/block and the end-of-argument-list weirdnesses). Why uglify that syntax to create an API that reads like instructions for setting up a cheap imported bookcase?

The languages I like are those that blur the boundaries between the language and its libraries.

In my opinion, APIs that are neither good examples of programming language nor the language of the domain do not serve this goal.

Re:Yes... mostly

pdcawley on 2008-03-12T23:05:16

My thinking is that people who are going to produce unmaintainable messes are going to produce unmaintainable messes no matter what road they take. This year it's internal DSLs, last year it was patterns, next week it might be computed gotos. Let's just be grateful that they've not discovered how callcc works.

Then again, I'm not sure there's a better way of learning how not to produce an unmaintainable mess than to make (at least) one and the reflect on how you messed up.

Re:Yes... mostly

chromatic on 2008-03-13T00:45:10

I'm not sure there's a better way of learning how not to produce an unmaintainable mess than to make (at least) one and the reflect on how you messed up.

The nice thing about weblogs is that you can mislead a lot of people before you learn your lesson. Then again, several parts of the Perl core documentation are outright wrong in terms of good style....

Re:Yes... mostly

pdcawley on 2008-03-13T07:19:17

The nice thing about weblogs is that you can mislead a lot of people before you learn your lesson.


Hey, if that gets 'em to their own personal lesson faster, where's the harm? Okay, so they might end up thinking you're an idiot for misleading them, but so what? They're probably right.