« They Shoot Presenters, Don't They? | Main | Playing with a Testing Library »

March 11, 2008

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d83451c41c69e200e550c4e2298833

Listed below are links to weblogs that reference The 'Language' in Domain-Specific Language Doesn't Mean English (or French, or Japanese, or ...):

Comments

she

I think there is another problem.
People seem to put together multiple paradigms as a "domain specific language". For example, someone said that BLAST is a domain specific language. BLAST contains only of 20 amino acids arrange in different order. So you end up with a text file that has like "PKKRKVSDNN" and so on.

Thats it basically. Sure this file is specific to the "domain" of biology but is this a domain specific language? I think no.
It lacks some power. Activerecord however is a true domain specific language as far as I am concerned.

However, there exists another problem:
on the one hand, we have interface oriented design (with a touch of DSL to it):
- order 3 pizza
or even funnier
- order 3 pizza in 3 hours if lowest_price_a_piece < 5 $

And the various component, what qualifies as a pizza, could be described too. I think for a user, this is pretty understandable, and I think a system should be able to both use such a language, and also present a FLEXIBLE GUI to the user. (Empower the user)

But what do you see in something like Activerecord? Everything must be valid ruby syntax! You cant just continue if you have an error in the syntax ...
Ruby syntax is beautiful, it is the cleanest language as far as I am concerned, especially because you can omit the () at any time, but I dont think that a "perfect" domain specific language should struggle with syntax issues at all, at least not on the language level part.

For me, a real DSL is more these that were used in the game zak mckracken (although its ancient, and not a good example for today's world, but back then it was kinda cool).

Take your example of:
add.a.diary.entry.for("Lunch").for(August.10.at(3.pm))

It is quite nicely looking, but why would we need to use the . ?
Of course because ruby needs them. And the DSL needs to reside on the ruby-level.

On the one hand you have all of ruby power, but I think it would be better to have a language that lies outside of ruby, and providing the user with a fault-tolerant, terse, human-readable syntax (which btw is my main problem with XML, it tends to get very verbose and ugly IMO)

Sammy Larbi

The focus should be on the D in DSL, whereas some of us are fixating more on the L. I can see it.

Steve Campbell

Great post. 100% agreement from me.

Michael Hartl

N.B. A pidgin is a rudimentary proto-language. When a pidgin evolves beyond a simple combination of its parent languages to become a language in its own right, it becomes a "creole". So "domain-specific pidgin" might be a useful term.

Stephan

As far as RSpec is concerned, there's another issue: While your code might satisfy all the specifications and stories you can put together with RSpec, that might not be enough.
The reason for this is the fact that RSpec changes the tested object by adding methods which end up as methods of Object. This in turn means that you didn't actually test the thing which is used in the production environment, but something (if only slightly) different. But this difference might make, well, the difference. (Yes, I know that I am nitpicking.)
I think that RSpec really is a good tool to specify desired behaviour, but there is a reason that specification and testing are different tasks in software development. Mixing these two up might cause trouble.

Bil Kleb

How does Jay Fields' Expectations testing DSL compare with the 'specs? http://blog.jayfields.com/2007/12/ruby-expectation-gem.html

Eric Anderson

Enjoyed the article very much. I have noticed a number of things lately popping up that I think are trying too hard to be English. Your last example is clearly crossing the line but there are some places where it is gray. For example in ActiveSupport we have:

3.days.from_now

On one hand you might argue this is going too far. On the other hand this notation is the easiest method of doing date manipulation I have ever seen. Prior to using it I always had to look up the reference documentation whenever I deal with dates. Now with this syntax I can always do whatever manipulation I need off the top of my head.

The reason I bring this up is that your last example is really just an extreme version of 3.days.from_now. Your example is obviously wrong but the ActiveSupport date manipulation is genuinely useful. So my question is when does it move from genuinely useful to obviously wrong. It seems the line is blurry.

My other complaint with DSL's is that with languages like Ruby most of them have become internal DSLs. Now internal DSLs have some nice advantages. No parsing, full power of a language, etc. But I don't think all DSLs should be internal. Sometimes you can get much more expressive by breaking the confines of your language syntax.

Maybe things like Rubinius will give us a system where we get the ease and integration of creating an internal DSL but the flexibility of an external DSL. But until then people need to really think if their DSL should be internal or external.

Matt

"By doing so you might add to its readability, but I can guarantee that you'll be taking away from its writability". So it's a trade-off, and actually it's often not a bad trade-off to err on the side of readability rather than writability. We read code more often that we write it. And this is why Perl takes lot of flack -- as (it's perceived that) ease of writing takes precedence over ease of reading.

In your last example, it's really easy to comprehend the intent of the code. That's a big plus, in my book. A minus is that it's more wearisome to write -- but a more serious issue is the actual action of the code is obscured. Win some, lose some, but I'm not yet convinced of the absolute demerit of fake-English DSLs.

Dave Thomas

Eric:

I agree that 3.days.from_now is a wonderful little DSL. But, I think it's readable English because good names were chosen for the methods, in the same way that array.size is readable. The intent here was to find a way to express scaling and relative times, and not first and foremost to create an English-like syntax. Having worked out the way they wanted it to work in the domain (that is, they'd use seconds as the unit, seconds from epoch for absolute time, and not worry about checking the usage), the readability came along easily. They didn't have to distort the code to make it English-like.


Dave

Dave Thomas

Matt:

The tradeoff is two-fold: writability, but also all the additional code that you need to carry around to implement the DSL.


Dave

Dafydd Rees

Hooray! At last somebody well known is saying this too. Natural languages have serious problems for programming - as the COBOL standards committee found in 1959.

I don't like it when people contort their object model - shifting responsibilities around to the wrong places just to make random fragments of code "read more like English". This isn't a subjective thing this approach can end up with code that runs more slowly because the methods are in the wrong classes.

I discussed this in "When shouldn't you use a DSL?" at http://skillsmatter.com/menu/844

steve

I have also been trying to get into Applescript for years too, and I also fail every time. Around me, other people are making Applescript do something, and yet I can't make it do anything.

They have told me that I'm just too much of a programmer, but it seems the only way to do Applescript is to memorise vast passages of existing code like a Bible scholar.

Stephan

Another issue with DSLs in "Not Quite English" is the fact that many programmers are not very fluent in English or are native English speakers. Which means that they will struggle with the English part for the DSL.
Now, while most programming languages derive parts of the language from English (keywords, class and method names etc.), these parts are easy to understand even without understanding English very well. (At least they were for me when I started programming quite a few years ago when I didn't know much about the English language.)
In the end I think a DSL shouldn't be designed to close to a natural language (English or not) because it makes it harder to learn - and might interfere with your English learning (which I think you should also do).

Leslie Viljoen

A language that suffers heavily from the problem above is the text adventure design language Inform 7 (http://www.inform-fiction.org). It is an amazing effort, and when using it as intended it makes writing an adventure game a pleasure, but when you start using your knowledge of English to accomplish new things, your knowledge interferes and Inform misunderstands.

Still, I think Inform 7 may be the furthest anyone has gone in making an English computer language.

Ben Kimball

Dave, fantastic post. I've never been able to clearly express why I dislike AppleScript, but you've done it beautifully. I'm still a fairly new Rails programmer, with only a couple of applications completed, and I'm still sticking with Test::Unit. rSpec looks seductive, and I'm glad to read your critiques.

has

AppleScript is a curious case, and worth a little more analysis, IMHO.

AppleScript's keyword-oriented appearance is in itself a Good Thing, given that one of its major requirements is that non-programmers should be able to understand a program's general purpose and action just from reading it. In order to achieve that goal, most of the usual symbolic cues that describe a language's semantics - dots, braces, etc. - were removed from the AppleScript syntax. This brings us to AppleScript's primary problem: rather than finding some other way to supply this structural information to the user - e.g. via a structure editor such as Carnegie Mellon's Alice - it was *left out completely*. So while it's very easy to read an AppleScript and understand _what_ it does, it's damnably hard to figure out exactly _how_ it does it, because the syntax effectively obfuscates, not clarifies, the language semantics. Hence AppleScript's reputation as a "read-only language".

A secondary problem with AppleScript's appearance is that it accidentally encourages unrealistic user assumptions. With AppleScript looking so English-like, naïve newcomers automatically assume that because it _looks_ like English, it will also _behave_ like it. Doesn't matter how many times the documentation says "English-LIKE syntax" or lists all its formal rules and restrictions, the moment that a newcomer sees that AppleScript code looks quite like something they already know (i.e. written English), they *immediately* form all sorts of very strong associations and conclusions about its nature, which then have to be undone the long, hard way. Again, presenting it within an unfamiliar environment such as a structure editor would have gone a long way to preventing these assumptions being prematurely formed - slowing new users down a bit so that they can grow a more realistic mental model over time, while still retaining the initial high-level readability that makes the language appealing to the end-user audience in the first place.

(There are other problems too, but most of these are actually caused by applications' badly designed/implemented APIs and frequent lack of adequate API documentation - a problem which is hardly unique or specific to AppleScript.)

I do believe AppleScript should serve as a significant object lesson to anyone else thinking of designing their own language, domain-specific or not, and I heartily recommend the following paper by one of the original designers:

The Development of AppleScript (W. Cook, 2006)
http://www.cs.utexas.edu/users/wcook/Drafts/2006/ashopl.pdf

HTH

has
--
http://appscript.sourceforge.net

has

p.s. & FWIW, here's your AppleScript example in Ruby (with apologies for lame formatting):


require 'osax'; include Appscript, OSAX

this_file = osax.choose_file(:invisibles => false)
begin
ie = app('Image Events')
ie.launch
this_image = ie.open(this_file)
this_image.scale(:to_size => 640)
this_image.save(:icon => true)
this_image.close
rescue => e
osax.display_dialog(e.to_s)
end


While the extra syntax makes the semantics clear for someone who already knows Ruby, to someone who doesn't, it's just extra noise that provides no help in understanding the script's detailed mechanics while also making it harder to grasp its overall purpose.

So I think AppleScript's original designers had the right overall idea, considering the type of audience they were targeting. It's just the execution that they ultimately flubbed, although this is perhaps understandable given that end-user programming research wasn't nearly as advanced at the time and they were largely working from a blank slate.

(OTOH, it's just a little irksome that after 15 years Apple are still beating the same lame horse painfully onwards, instead of learning from its mistakes and coming up with a better replacement; but that's a separate rant for another time and place...)

Bala Paranj

Awesome post. I totally agree that the RSpec is not a DSL. I always had to look for the documentation when I had to write the test.

Kasper Graversen

Hi. I try in SqlOrm to define a DSL for dynamic sql queries

sqlorm.sourceforge.net

the main motivation has been to enable programmers to specify the various "bodies" an sql statement consists of irregardless of the required order of these bodies. The framework takes care of this. You could say that the domain here is just plain sql.

Hermann Schmidt

Nice post, Dave.

I've just finished a Ruby EAI test tool, which has a DSL on top do define parameterized testing scenarios.

I think the most valuable usage of Ruby internal DSL techniques (metaprogramming) is to express relationships between things by syntactical structure (nested blocks) rather than explicit method calls - which are still in place behind the scenes of course.
Also, presenting domain-specific vocabulary as if it was part of the language is a great technique. With vocabulary I mean single words like in my case "testsuite", "scenario", or "activity".

The language is targeted at test designers, who need to learn a this domain-specific vocabulary. That makes the most sense to me.

The idiom to form sentences with dot-separated methods did not attract me much. I've seen a piece of Java code lately, I think it was part of the Apache ServiceMix, where this idiom has been used. It did not help me to understand anything easier. It was way over the top.

One should not squeeze idioms out of a language that has not been built for it, just because it is currently hot. It's cool with Ruby, but Java has not been designed for this. Even C with its macro preprocessor was closer :-)

Michael Hunger

I think you have to differentiate with regard to the target audience of your DSL. If it is a business - DSL (see Jay Fields) you must put much more effort in simple structures (small vocabulary, simple grammar but expressive/concise) for easy reading AND writing by business people. There an external DSL is almost always preferrable (no programming language syntax rules). Another important thing there is editor support. We are all used to our intellisense, type completion IDE's when programming statically languages. So editor support with highlighting, word completion, grammar check and preferably an simulator for the dsl-expression just typed in is very helpful in this regard.

On the other hand you have developers. These are used to programming languages and their syntax requirements. So you can build fluent, concise APIs that expose the functionality in a readable, human(developer) friendly way.
Here the advantages of internal DSLs are a real benefits, integrating the DSL into you application is dead easy, having no extra parsing step helps as well and the users are used to this kind of syntax and will have no problem reading and writing these more program-like DSLs.
You can skip all the "English like" syntactic sugar that adds not so much value in readability but makes writing the expressions harder.

Michael

adding to the examples used by Dave:
* Rake, Ant
* Date & TIme API
* JMock
* Jequel - an internal fluent Java-SQL-DSL, using the real tables and fields which allows you to program SQL in a typesafe manner, see http://jequel.de
Example:
select(ARTICLE.OID)
.from(ARTICLE, ARTICLE_COLOR)
.where(ARTICLE.OID.eq(ARTICLE_COLOR.ARTICLE_OID)
.and(ARTICLE.ARTICLE_NO.is_not(NULL)));

More Resources: Martin Fowlers DSL book in process:
* http://martinfowler.com/dslwip
* Thoughtworks DSL podcasts

Adam Hooper

It's a relief to see that my hatred of RSpec's syntax is justified. The learning curve is enormous purely because the syntax is utterly nonsensical. (I like the rest of RSpec, and I feel it would work even better with domain-specific syntax and method names.)

Kevin

I take similar issue with some of the conventions used in DataMapper: http://kbullock.ringworld.org/2008/9/9/too-much-cleverness

Specifically, the addition of methods like #lt and #like to Symbol. You need Lisp-style full macros to add syntax like these frameworks want to; Ruby's syntax is actually fixed though, so people fake it by monkey-patching methods into core classes.

caddzooks

It was quite interesting to read this discussion on DSLs, with only a single mention of the programming language family that I and many others regard as the best way to create DSLs.

That would be LISP, and its cousin Scheme.

My opinion on that lies in the nature of the langauge, which has no syntax, and unlike any other language I'm aware of, is fully extensible.

LISP has no operators, statements, or constructs. In LISP, data and code have the very same structure, allowing LISP programs to manipulate LISP code as easily as they manipulate LISP data.

That quality, in conjunction with LISP macros, makes functional and metaprogrammming incredibly simple. In LISP, a DSL is just an API, so the DSL user/programmer us not confined to the DSL itself, but can can access everything LISP offers, making the DSL scalable and further extensible by DSL programmer.

Steve Cooper

I'm not convinced that the failed DSLs you mention are really DSLs at all.

Applescript is a general-purpose language, and not specific to any particular domain. So it's really just an bad language. I agree that general-purpose programming in english won't work.

test/spec and rspec are written in ruby, so it's more of an API than a true mini-language.

There is value writing mini-languages that are small, concentrate only on a few very narrow tasks, and have their own dedicated parser. Consider this example -- a DSL for describing company organization;

~~~~~~~~~~~~
Alf is a programmer.
Bill is a programmer.
Charlie is a technical writer.
Alf, Bill, and Charlie report to Dave.
Dave is a manager.
~~~~~~~~~~~~

Now there's a DSL that gains a lot from the english representation. Absolutely anyone in the organization can read that program; you can copy and paste the program into a report to the CEO if you want. And you can use the parser to programatically generate the org chart in Visio.

The comments to this entry are closed.

Now in Beta

  • Programming Ruby, 3rd Edition
    Third Edition, Covering Ruby 1.9, now available
My Photo

Pragmatic Stuff

Photos

  • www.flickr.com
    This is a Flickr badge showing public photos from pragdave tagged with pragdave_badge. Make your own badge here.