My last blog entry was on my mind quite a bit last night. I kept coming back to the same questions - when are narrative languages appropriate? And when are they overkill?
I started to think a bit about some of great APIs I've seen that live in a completely different world. One is an embedded DSL for music composition from Paul Hudak's book The Haskell School of Expression. Here's a little example from the book:
funkGroove
= let p1 = perc LowTom qn
p2 = perc AcousticSnare en
in Tempo 3 (Instr Percussion (cut 8 (repeatM
((p1 :+: qnr :+: p2 :+: qnr :+: p2 :+:
p1 :+: p1 :+: qnr :+: p2 :+: enr)
:=: roll en (perc ClosedHiHat 2))
)))
It is a little scary at first glance, but it becomes clearer once you know that en is eighth note, qnr is quarter note rest, and the symbols :+:and :=:are sequential and parallel composition; i.e., play after another phrase and play at the same time as another phrase, respectively.
The thing that is very cool about this DSL is that you can easily format your code to see phrases above or below phrases that will play at the same time.
The variable names p1 and p2aren't very informative, but I do think that they aren't quite as shocking as they would be in a conventional program. This DSL is completely about structure. It's about building up a piece of music and being able to tell, at a glance, whether it is what you want it to be.
The abbreviations for notes and rests actually look like they work well within it. It pains me to say that, because I usually hate abbreviations with passion.
No, it's hard for me to imagine a narrative, fluent, or English-like API for this problem that I would like better than the symbolic approach. I guess it has something to do with the domain. People don't talk about how one note follows another as much as they listen for notes or see them on a page. For people who read music, it is a very spatial domain.
But, maybe it's more than that. Maybe the reason why the symbolic approach works so well here is because these programs are about structure. The order and arrangement of the notes has a very direct meaning. Other domains like time and money, are less structural and more semantic, so it seems that they might be more suited to the narrative approach.
Perhaps the choice between narrative and symbolic is more than just style?

Comments (5)
I can't help but feel that most DSLs are an attempt to get around the fact that our representation of programs is still mired in ASCII. The party invitation I sent out last week combined graphics, a map, and some funky amateur typography; why can't I be the creative with my programs? In particular, why should Hudak have to wedge all of his ideas into tokens composed of 7-bit ASCII (actually 6-bit, since he's not even allowed to use the whole 7-bit character set)? There's no technical reason why he couldn't display his music *as music*, using someone else's parser and interpreter plugins to render/play it. Why do we build these capabilities for everyone else, but not use them ourselves?
Posted by Greg Wilson | January 12, 2008 3:40 PM
See also LilyPond, a music typesetting program with a Lisp DSL.
Posted by Patrick Mueller | January 12, 2008 3:43 PM
(to Greg) It seems that people try that periodically. The Fortress programming language had the specific goal of allowing math to look like math. The question I always have is whether that sort of thing could ever take off if the choice remains: special keyboards, menu selection, or unicode escapes.
Posted by Michael Feathers | January 12, 2008 3:45 PM
I thought it was pretty well established that symbolic representation is best for music, and a well defined, specific one at that: sheet music.
It seems any systematic representation of human thought could be boiled down into a standard symbolic representation (i.e. language, mathematics, chemistry, music, computer instructions, etc).
I'm guessing that in most computer software, the problem/business domain could be eventually represented in a symbolic form. The problem we face is that we try to shoehorn the natural symbolic language of the domain into a different (and differently-purposed) symbolic language (the programming language).
Perhaps we should stop trying to bend Haskell, Ruby, C#, Java, and others into something they're not and work on a way to make writing compilers/interpreters for natural symbolic domain-specific languages. I know this is being done on several fronts to varying degrees of success. It seems clear to me that trying to force these other symbolic representations into a completely different symbolic representation is a zero-sum game and everyone loses.
Posted by Chad Myers | January 12, 2008 4:59 PM
(to Patrick) Thanks, I'll take a look at it.
To me, the neatest thing about Hudak's DSL is that it is a music generation system. I've always had a soft spot for those.
One of my favorite bands a long time ago was named 'Doctor Nerve.' It was formed by an ex-actuary who decided that he wanted to hear people play outrageously complicated music that had no human prejudices; music that no composer would write if, for instance, he knew what was hard or easy on a bass guitar.
He used a language named HMSL (Hierarchical Music Specification Language) and wrote some programs that generated scores within certain parameters, then he taught them to his band mates. Very bizarre stuff.
Posted by Michael Feathers | January 12, 2008 7:42 PM