Domain-Specific Languages vs. Notation
spin.atomicobject.com
spin.atomicobject.com
This was what COBOL attempted to do, and far from having the intended effect (allowing non-specialists to program), it actually just created new breeds of specialists who could understand this new and really rather bad programming language.
Capybara's isn't that bad, although trying to make a more human readable DSL that uses XPath is a little ironic. The robot framework is probably the language that does this that I hate the most because it's turing complete and, IMO, actually less readable and usable than the language it was built upon.
I'm not arguing, of course, that we should go back to using COBOL. But lets get the facts straight. By 1997, according to Wikipedia, "there were a total of 200 billion lines of COBOL in existence, which ran 80% of all business programs." It was, in other words, a massive success. How does that prove that DSL's are no good?
It's a little hard to wrap our heads around the state of computing in 1959. I'll just say that at the time it was a difficult even for academics at big universities to get good access to computers. Most of the readers of this site weren't even born yet. Yes, of course, COBOL's out of date. If it weren't that would be a miracle.
DSL's may or may not be a good thing, but bringing up COBOL is perhaps not the most effective way to reach a valid judgment on the subject.
It doesn't stack up well compared to FORTRAN or LISP, which were both its contemporaries, neither of which were actually really designed with readability in mind, whereas COBOL was.
>DSL's may or may not be a good thing
This wasn't about DSLs in general. It is about the anti-pattern (dating back to 1959) of using as much pseudo-English as possible in a language in a vain attempt to make it readable, and actually making it more unreadable.
I dunno that I'd say that without substantial qualifications. Much as I hate COBOL, and little as I've used either, from what I remember of each I'd probably still prefer COBOL to Fortran for a large business application, if those were the only two choices I had.
I wouldn't want to use COBOL over Fortran for scientific computing, and I prefer Lisp over either for most things.
COBOL was a massive failure. It had a goal of producing a language that business people could use directly with no intervening programmers by being "English-like" and friendly. This totally and utterly failed.
These things are not contradictions.
Further, everything I know that was designed to be "English-like", cut out the programmers, and let the business people program directly has been a total and utter failure, on that metric. By contrast, there's a number of things that business people directly use all the time without programmers, like Excel macros, that aren't trying to attain friendliness through "being like English". Maybe there's something out there that has done both, but I've not heard of it.
I don't criticize COBOL for trying. It was an experiment that had to be tried, and I have strong opinions about it precisely because COBOL and others provide me the data points with which to have an opinion. But its popularity among programmers doesn't establish that it was successful in letting business people code directly.
I would agree, though in many cases (SQL particularly is a strong example) that's often more a failure of the organizations using the technology than the technology itself.
It doesn't matter if you have business-side analysts that can use SQL if you by policy don't let anyone outside of the IT side of an organization have access and tools that allow the user to use SQL directly against the database.
The IT-as-high-priesthood cult in organizations is strong, and resistant to any application of technology that challenges the priesthood. And this is, IME, especially true in organizations where the IT organization (and particularly its leadership) isn't particularly technically strong to start with.
Datalog is interesting because there is no statement order...it is pure declarative. Every transformation has an output that is bound to a unique identifier, which makes reasoning about order sequential even if the words on the screen are not. As great as SQL is, it would be better if we could go back to the foundings of relational databases and make Datalog the default query engine.
Despite this, SQL is the most successful logic/declarative language in the world. I think it's been argued that Prolog and logic programming stalled because SQL is good enough for the largest domain that logic programming is useful for.
Ultimately, I don't think it's any missing feature in SQL that makes it hard to understand large statements - it's just that large logic statements are hard. Maybe some way to make expressions more modular - incrementally constructing "adjectives" for use where clauses for example. But much as we all like our pet improvement to logic expression, I don't think that's the problem.
Interestingly, the thing I liked best about COBOL was the PIC clause, which was actually a notation for formatted output. It beat the hell out of printf, that's for sure.
I'm not one to denigrate syntax or readability, but I think it must without any question be prioritized below good semantics. The "Zen of Python" has some (but hardly all) this hammered out well
* Explicit is better than implicit.
* Simple is better than complex.
* Special cases aren't special enough to break the rules.
* In the face of ambiguity, refuse the temptation to guess.
Working in DSLs—and really there's no reason to think that we're not always working in DSLs nearer or further from our actual domain—should simplify concepts first and syntax later.I strongly disagree. You get what you wish for / focus on - if you wish for good semantics, you will get good semantics, but not necessarily readability. If you wish for readability, you may not get good semantics - but the point of having good semantics is readability, so...
This is the issue I have with the Zen of Python (versus the Principle of Ruby). The Zen of Python attempts to list out the things you should do so that you get Developer Happiness. Ruby just says "Go get developer happiness".
And so you get Python code that follows all the Zen of Python but fails to make you happy, and you have Ruby code that breaks all the rules of the Zen of Python, but does make you happy.
Given that what makes a good programmer happy amount to ease of use, effectiveness, reliability and speed (in an order dependent on circumstance), or more succinctly - if I am happy when I am effective... I'd rather be happy than right.
I personally think developer happiness is a very poor place to put your stock. I believe much more that the goal should be one of craft and if the mechanism is painful and difficult then this is merely the cost to play.
I think there's a lot of room for places where developers are made to be happy. Education is a HUGE target here and I'm happy to note that a lot of Ruby's early successes, I believe, were centered there. I believe happiness, convenience, and a little bit of absurdity are fine traits.
But when I want to get work done, when I want to make things to share and to last and to communicate my goals and intentions, then I want to suffer whatever is necessary to do that well. So, in my opinion, developer happiness be damned.
Then, again, it's also my perspective that developer happiness can perhaps be maximized in this way as well. But if you take it as your solitary goal then I don't think you're well equipped to make the whole journey.
Let's call the "smart interface with domain-specific verbs" a domain-specific interface, it would be just fine. But calling it a language is simply a term abuse.
Of course, with host languages that support user-defined syntax rules, an internal DSL may also have specialized syntax.
The cumbersome term you invented is not an accurate replacement for internal DSL.
[citation needed]
I'm playing the fool here - I do know what an internal DSL is but I think the term is entirely meaningless when you really think about it.
--edited
For example, this blog post walks through McCarthy's original specification for Scheme: http://programmingpraxis.com/2011/11/01/rip-john-mccarthy/
apply[fn;x;a] =
[atom[fn] → [eq[fn;CAR] → caar[x];
eq[fn;CDR] → cdar[x];
eq[fn;CONS] → cons[car[x];cadr[x]];
eq[fn;ATOM] → atom[car[x]];
eq[fn;EQ] → eq[car[x];cadr[x]];
T → apply[eval[fn;a];x;a]];
eq[car[fn];LAMBDA] → eval[caddr[fn]; pairlis[cadr[fn];x;a]];
eq[car[fn];LABEL] → apply[caddr[fn];x;cons[cons[cadr[fn];caddr[fn]];a]]]
This is a type of source code. Notice it even includes non-ASCII characters. But this code isn't executable as it is. It has to first be translated into a program, somehow. See the first reply at the original link, which I will not reproduce here, for brevity.It is a Scheme interpreter. The call to `evaluate` at the end of each test function is where the program gets interpreted. No, it is not a Scheme source file, but it is Scheme syntax, written in Python.
Similarly, LINQ to SQL is a SQL syntax written in C#. Your LINQ expressions are C# code that construct objects that will be interpreted in a SQL context. LINQ to Objects, on the other hand, is NOT a SQL syntax, it's just a library. Even though the function calls look exactly the same, because the C# code you write defines objects that then execute in a C# context.
Of course, that's not to say most "DSL"s haven't misused the term "language". I see it applied a lot to interfaces of chainable method calls. It isn't a new language, it's an exploitation of the existing language. The code still executes in the host language's context, it does not define its own contexts or semantics in any way.
Look at Emscripten. Is it C because that was what the code was written as, or is it JavaScript because that is what the code gets translated to? It's C, because it creates an execution context within the JavaScript code to recreate C semantics.
Look at this toy language I once wrote (https://github.com/capnmidnight/betty-boop/blob/master/loosp...) and a Pong game that uses it (https://github.com/capnmidnight/betty-boop/blob/master/pong....). Is the Pong game Scheme because that's what it was written as, or is it JavaScript? It's JavaScript, because though the code looks like Scheme, it executes like JavaScript, it's just a different syntax that gets translated away.
As far as I see it, you can certainly call your API / library a DSL when you have to write your own compiler rules for it in some capacity. Chef and Puppet code are not DSLs in this respect (especially Chef - the files have .rb extensions, gee) while SQL and CSS would count as DSLs free from being tied to a specific foundation language.
If I want to be a bit more specific, I think a DSL needs to be independent in syntax and semantics from any implementation environment or platform and that by leveraging the compiler of your implementation language that it limits the "language" aspect of the DSL. I believe most people are concerned about the "DS" aspect and in this respect that reduces a DSL to being just a higher-level API - an API is not necessarily Turing complete, after all, and while some APIs require some parsing to use, they are still.
An embedded language like how Lua is used oftentimes is not a DSL to me because it is general purpose and is perfectly fine to implement another DSL - a DSL to me should also imply that you can't use it to implement another arbitrary DSL. This will blur as what used to be DSLs add features that make them Turing complete (lots of crazy things possible with SQL and CSS these days).
I don't like to be a terminology Nazi or something, but I have no real rational explanation for why "DSL" in practice rubs me funny.
There is something really genuinely different about a "DSL" which has reached the status of being totally externalized. On one hand you're now forced to more completely define the semantics/syntax from scratch (you can't bootstrap, though I think to some degree that 'definition by implementation' here is a big fallacy) but then on the other you're also facing a much greater task if your primary end goal is to just better focus on the domain.
In my opinion, DSLs are just languages with an intent to hit a target domain. External DSLs, as I call what you call DSLs at large, are one mechanism for doing that. Internal DSLs, which are not really distinct from APIs + their conventions, have the interesting property, however, of arising in layers. This aids composition and speed to develop.
But they absolutely suffer from being compromised on semantics and syntax due to their embedding. And before a Lisper comes by and talks about macros, I think the tradeoff is fundamental. The more you bear on the "underlying" language in your DSL the more you must compromise.
Genuinely, a very high-value DSL ought to be externalized, I feel.
http://en.wikipedia.org/wiki/Domain-specific_language#Usage_...
models: https://github.com/snoyberg/haskellers/blob/master/config/mo...
routes: https://github.com/snoyberg/haskellers/blob/master/config/ro...
DSLs are parsed/compiled/interpreted. If you're doing one of those things, and the words represent concepts in the problem domain? You've got a DSL. Otherwise you just have a well-named API.
But I may have missed it. I failed to see the point of this article -- perhaps I am in violent agreement and do not realize it!
I think this line lead to believe so , but reading on...
>>But emulating the English language—complete with nouns, verbs, and prepositions—is simply the language of the domain, not a truly domain-specific language
And this one too :
>>A key difference between using the language of the domain and a domain-specific language is that a true DSL—notation—is not only suited for expressing problems and solutions, but also for getting from one to the other.
Basically he wants to state about notational convenience,degree of expressiveness and ease of notational operations with the math example.This ease of operation leads to better formal verification and better spec translation.He then goes onto talk about notations used in Music etc..
The benefit of a DSL can be that you can do verification etc on the semantics of the domain. An API with handy naming may not be able to do this trick.
Note that the readers and writers of a DSL may be very different audiences: the readers can be domain experts who give feedback while the writers may be software engineers.
I got a bit cynical when the list stopped there. But maybe these languages are indeed as powerful and expressive as the Lisp of the day?
Not if you're using embedded DSLs, which are basically rich APIs supporting variables and control structures. They can be as fluid as simpler APIs, yet have strictly greater expressive power.
Take a look at this person's CV [0] and his "Domains and Customers" section [Page 20], you will see where all DSLs are applied.