You Can't Get There From One of These Heres

chromatic on 2008-09-10T06:33:49

An internal DSL is just a particular idiom of writing code in the host language. So a Ruby internal DSL is Ruby code, just written in particular style which gives a more language-like feel. As such they are often called Fluent Interfaces or Embedded DSLs. An external DSL is a completely separate language that is parsed into data that the host language can understand.

...

I see DSLs as having two main benefits.... The most interesting benefit, however, is that a well designed DSL can be understandable by business people, allowing them to directly comprehend the code that implements their business rules.

Martin Fowler, DSL Q and A

Like minicomputers of old, I can program my microwave by entering programs on its keypad. Unlike minicomputers of old, those programs are not Turing Complete. My microwave has a domain specific language which allows me to control the amount of microwaves it emits and the length of time it emits those microwaves. There are some complications; you have to get the order of operations right (first time, then power), and the syntax for entering times is slightly complex (two-digit values are in base 10, while three digit values are in base 60). Yet it's also simple enough that non-programmers can use the device regularly without realizing that they're writing simple programs.

Now imagine that they had to program my microwave by using a fluent interface written in a general purpose host language. Suddenly the two-digit/three-digit assumption for base switching is inappropriate; there may or may not be a time context in which to interpret numbers, for one thing, and a leading zero may imply the use of octal as it does in many C-like languages.

While there may be an easy and obvious way to reheat chicken parmesan with this fluent interface, there may be multiple effective ways to count the time, and the syntax and semantics of seemingly equivalent programs may differ in efficacy, efficiency, and side effects. Of course, it may be easier to reheat pizza, where a minute at half power and thirty seconds on full power is most effective -- you could make a separate function to reheat three slices. (I wish I could.)

You can get the same effect both ways. The important consideration is of benefits and drawbacks.

Martin is completely right that using the language of the domain effectively can help communicate domain concepts clearly between business people and technical people, but I believe he's wrong that a so-called "internal DSL" is effective at doing so.

Why?

Because (as people who dislike Perl oft expound) understanding a piece of code requires you to understand the operations and idioms used in the code.

To understand a SQL query containing a join (a declarative domain specific language for managing relational data), you need to understand (some portion of) the relational model. You don't have to understand the indexing algorithm used to select matching rows or the storage format of rows in relations in a persistent medium.

To understand the related procedural code to perform the same query without using SQL, you have to understand the indexing algorithm and the storage format -- or at least how to use API calls to perform those operations. The possible implementation decisions and semantics are much broader.

If Moose had a declarative, compile-time language for declaring classes and attributes, you could compare it to the existing "language", which relies on Perl parsing rules and quoting rules and may rely on order of compilation rules in some contexts.

While I agree that a reasonably skilled participant in a domain may be able to get a rough impression of the business logic expressed in a so-called "internal DSL" -- certainly enough that she may be able to debug blatant logic errors -- the knowledge of the host language's semantics is necessary for a direct comprehension of the implications embedded in that pidgin. You still have an API Town mailing address, no matter how much you want to pretend you live in the wonderful Land of I Can Writed a DSL (unless you want to claim that we're all born with an intrinsic understanding of Ruby's variable/method scoping/shadowing rules and the difference between a Symbol and a String, like some sort of Jungean glossalaia).


I so disagree with you

systems on 2008-09-10T20:46:48

To start I am not a fan of the modeling gang like Martin Fowler and his buddies of the agile manifesto, I believe they ruined the topic (software modeling) for generations to come, they took something smart and turn it into something dumb and silly, and not smart at all!

But I have to say, every now and them being the veterans that they are, something smart comes out of them.

I believe that the IT literature, writing or whatever suffer from ill defined definitions.

For example, surf the net for definition of thing like BI, Data Mining and Transaction Management System. Whatever definition you will find, it be far from the actual product.

DSL, is kinda, one of these term, that people tend to over complicate, which doesn't help outsiders (Business people), or insiders (IT people) who are new to the concept.

I do like Martin's DSL categories, they are simple, clear, straightfoward and useful.

I will paraphrase what you said he said to clarify why I think they are useful.

You have two kind of Perl DSL. Internal, and External.

Internal DSL, is Perl Code a library, with an interface that clear, simple and intuitive, to the extent that none Perl coders, can correctly guess what the code, without prior Perl experience and with very little (and preferably without) training.

External DSL, is a new language, specially crafted to solve a specific type of programs. Like regular expression.

And to elaborate furthur, and explain why DSL good not just of Business people, is not just about syntax, DSL is about providing delcative solution vs. procedural ones.

Using an Internal or External DSL, should shield you from reverting to tradional program languages constructs like Loops and Conditionl branches. You should be able to only use the DSL code to solve the Domain Issue by coding what you want done and without having to use loops or conditional branches and by doing so reverting to a procedural style.

Moose does exactly this, I declare clases using Moose provided syntax, I don't use previous, older or traditional Perl OOP idiom. And this makes Moose code shorter, clearer and more intuitive, I don't read algorithims when I read Moose code (the code used to create classes and types), which is specifically what in my opinion make Moose worth using.

One thing I dont know, is, if Moose is Internal or External DSL, and according to most of the Moose tutorial I read, I should not care.

Moose is probably a hybrid DSL, as it introduce new Keywords (or so they say) and other than that its Perl code.

I ultimatly find the DSL categories introduces by Martin useful, they allow peole to answer simple and common asked questions. Like is this syntax Perl Code or an External DSL. The differentiation can help developer at different better read, learn and teach the code. Better communicate using smart, clear well defined term that may have the effect or reducing the complexity of a complex concept

I hope i was clear, and not to long, and that my message got through, and was perceived as smart.

I disagree!

systems on 2008-09-10T21:07:47

To start I am not a fan of the modeling gang: Martin Fowler and his buddies of the agile manifesto, I believe they ruined the topic (software modeling) for generations to come. They took something smart and turn it into something dumb and silly (and not smart at all)!

But I have to say, every now and them being the veterans that they are, something smart comes out.

I believe that the IT literature and writings suffer from ill defined definitions.

For example, surf the net for a definition of things like BI, Data Mining or Transaction Management Systems. Whatever definition you will find, it will be far from the actual product, that most developers will create, and most business users will use.

DSL, is kinda, one of these terms, that people tend to over complicate, and this doesn't help outsiders (Business people), or insiders (IT people) who are new to the concept.

I do like Martin's DSL categories, they are simple, clear, straightfoward and useful.

I will paraphrase what you said he said to clarify why I think they are useful.

I'd say you have two kind of Perl DSL. Internal, and External.

Internal DSL, is Perl Code or a library, with an interface that clear, simple and intuitive, to the extent that people with no Perl training (or very little), can correctly guess its meaning

External DSL, is a new language, specially crafted to solve a specific type of problems. Like regular expression.

And to elaborate furthur, and to explain why DSL is good, not just for Business people, and that it is not just about syntax. DSL is about providing delcative solutions vs. procedural ones.

Using an Internal or External DSL, should shield you from reverting to tradional program languages constructs like Loops and Conditionl branches. You should be able to only use the DSL code to solve the Domain Issue by coding what you want done and without having to specify step or write algorithms using loops or conditional branches and explaining how the problem should be solved.

Moose does exactly this, I declare classes using the Moose provided syntax, I don't use previous, older or traditional Perl OOP idiom. And this makes Moose code shorter, clearer, cleaner and more intuitive, I don't read algorithims when I read Moose code (I mean the code used to create classes and types), which is specifically what in my opinion make Moose worth using.

One thing I dont know, is, if Moose is Internal or External DSL, and according to most of the Moose tutorial I read, I should not care.

Moose is probably a hybrid DSL, as it introduce new Keywords (or so they say) and other than that its Perl code.

I ultimatly find the DSL categories introduces by Martin useful, they allow peole to answer simple and common asked questions. Like is this syntax Perl Code or an External DSL. The differentiation can help developer at different better read, learn and teach the code. Better communicate using smart, clear well defined term that may have the effect or reducing the complexity of a complex concept.

I hope i was clear, and not to long, and that my message got through, and was perceived as smart.

For example how do you feel about the follwing statement: " ... technically, regex are hybrid DSL in Perl, but they lean more on to the external pole of DSls. You can write a Perl Regex without having to know most of Perl. The regex part of the program that is. Which means, it is easier to delegate Regex writing to outsiders! Because Regex is more external"

Re:I disagree!

chromatic on 2008-09-11T07:11:41

Internal DSL, is Perl Code or a library, with an interface that clear, simple and intuitive, to the extent that people with no Perl training (or very little), can correctly guess its meaning....

That's like suggesting that I can understand technical jargon in Danish by guessing at apparent cognates. I might be right once in a while, but that's luck. The fact of its jargonness and my familiarity with that jargon doesn't make it suddenly not Danish, such that my unfamiliarity with Danish ceases to be a problem.

Using an Internal or External DSL, should shield you from reverting to tradional program languages constructs like Loops and Conditionl branches.

To my mind this is the difference between declarative and procedural languages and has little to do with pidgins, creoles, jargons, or languages.

Moose is probably a hybrid DSL, as it introduce new Keywords (or so they say) and other than that its Perl code.

If that were true, then any Perl module which exports symbols provides a DSL, which is clearly not true (at least if DSL should mean anything). That's not quite true, because in Perl you can change the way perl parses certain tokens with prototypes, but some people keep insisting that internal DSLs are different from fluent, domain-appropriate APIs.

For example how do you feel about the follwing statement: " ... technically, regex are hybrid DSL in Perl, but they lean more on to the external pole of DSLs...."

It's very clear that regexps are a true DSL, as is m4, GNU Make, SQL, the Sendmail configuration language, procmail....

Really, it isn't that bad

btilly on 2008-09-10T22:29:47

About a decade ago I learned the trick of writing a data-driven Perl program. The data comes out of a Perl data structure in a configuration file.

Despite the fact that the configuration is pure Perl and could potentially do anything you can do in Perl, in practice I've been able to show it directly to a domain expert with no knowledge of Perl, they read it, we can talk, and they generally don't have trouble editing it.

Going in a different direction, both Class::DBIx and Rose::DB come with pure Perl query interfaces. Those interfaces are what Ruby folks would call internal DSLs, and they are used to hide the details of SQL from a programmer who only knows Perl. In other words programmers do not just produce this kind of interface, they may consume it as well. And an interface aimed at a programmer can be richer than an interface aimed at non-programmers.

Taking this idea a bit farther, technical users may be comfortable using a general-purpose programming language despite not being programmers. A good example of this is the inclusion of AutoLISP in AutoCAD. All they did was take a simple dialect of Lisp and add a bunch of domain specific functions to it that were specific to the product. But the result was a programming language that plenty of non-programmers found very, very useful.

If the Ruby folks want to imitate that everywhere and chant about DSLs, that's their business. But the basic idea isn't intrinsically stupid or useless, and I've seen it work in practice.

Re:Really, it isn't that bad

chromatic on 2008-09-11T07:22:46

All they did was take a simple dialect of Lisp and add a bunch of domain specific functions to it that were specific to the product.

My goodness, if other programmers realized that this were possible, we'd have a revolution on our hands! It may be hubris for me to presume that I could potentially name it, but how about the term "structured programming"?

I know... I kid, mostly because even a good macro assembler offers that kind of abstraction.

Despite the fact that the configuration is pure Perl and could potentially do anything you can do in Perl, in practice I've been able to show it directly to a domain expert with no knowledge of Perl, they read it, we can talk, and they generally don't have trouble editing it.

That's fine, and that's good, but that doesn't change the fact that they are still writing Perl code (and that's fine and it's good too).

If the Ruby folks want to imitate that everywhere and chant about DSLs, that's their business.

I suspect that the Ruby folks mostly want to sat "Hey look, this code reads almost like English!" without admitting that the concomitant definition of English is "bad poetry written by a computer passing familiar with the grammar rules of a wind-up Yoda toy, and sprinkled with random punctuation in the wrong places!" You know, like the nonsense that "Python is executable pseudocode."

Internal DSL...

Alias on 2008-09-11T00:49:32

So now at least I finally have a term (albeit a terrible one) for what Module::Install gives you.

I just wish that "Internal DSL for Module Configuration" didn't end up having the same level of weasel as "Democratic Republic of North Korea"

Re:Internal DSL...

Eric Wilhelm on 2008-09-11T01:15:30

You could just call it code. Too bad it isn't declarative or you could call it a declaration, right?

My microwave has a bacon button -- which I use to make coffee.

Re:Internal DSL...

jrockway on 2008-09-11T14:06:20

Mmm... bacon coffee.