4 ms·
> Isn't a DSL just syntactic sugar in most cases? I don't think so. Maybe with things like LINQ, but in many cases a DSL lets you abstract things to such an e
by da_chicken 9y ago
> Isn't a DSL just syntactic sugar in most cases?
I don't think so. Maybe with things like LINQ, but in many cases a DSL lets you abstract things to such an extent that you get a new way of thinking about the problem. That's why DSLs are almost always very high level languages.
SQL and regex are the obvious counterexamples, where you don't describe how to return the data you're looking for or how to store it on disk, you just describe that data and the language does the work for you. That's a completely different way of thinking about a problem compared to procedural logic. The languages allow you to describe very complex data in an explicit and unique manner, and in doing so allow you to abstract what the data is from how the data is maintained. Obviously, that can bite you if you structure your DB poorly, but on the flip side it allows people to learn how to use very complex descriptions of what are essentially abstract concepts instead of needing to know details that are extremely easy to screw up. Declarative programming is extremely powerful because of this, and it allows for extremely complex systems to be built on top of this new layer of abstraction.
A shell is another counterexample where being "just" semantic sugar is really oversimplifying it. You're in a fixed context with a default function, so you get a lot of acceleration over having to spawn all those processes by hand. You're stripping out so much overhead code that you're into a new level of abstraction where -- unless you need to -- you don't think in terms of procedural logic.
For a less straightforward answer, a generic programming language would be like a hex editor, whereas a DSL would be like PhotoShop (or even Paint). Sure, a hex editor can modify any type of file in any way, but the power of PhotoShop comes from all the power you get out of being domain specific. It's not just the additional built in functions the program gives you, it's also the manner in which the data are presented that allows you to see things which you simply would miss at the hex editor level. Here the abstraction is allowing you to see what the data actually represent instead of just seeing how the data exist in the computer.
- kerkeslager 9y agoLet's take one of your "obvious counterexamples": Exhibit A: [A-Za-z]\w*\(\d+(,\d+)*\) Exhibit B: cat(or(range("A","Z"), range("a", "z")), zero_or_more(alphanum()), "(", one_or_more(digit()), zero_or_more(cat(",", one_or_more(digit()))), ")") Exhibit A is absolutely syntactic sugar for Exhibit B. Regex is great if someone has already implemented a regex engine for you. But a key part of the post you're responding to is that it's talking about writing a DSL yourself. I can write the functions to run Exhibit B in probably 3 hours. I'd challenge you to write a reasonably language-integrated Regex engine in under 3 days, even assuming you have a good understanding of the domain. That difference in implementation time is going to take a while to pay off in composing actual regular expressions. And regular expressions are a very simple DSL. A more complex DSL would take longer.
- Bjartr 9y agoI think, taken to the extreme, all programming languages would then "just" be syntactic sugar over lambda calculus
- mtreis86 9y agoGreenspun's tenth rule: Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
- deleted 9y ago[deleted]
- kerkeslager 9y agoThat's true, but I think you look at my example you'll see that it's not that extreme. There's a 1-to-1 correspondence between each function call in Exhibit B and each semantic element in Exhibit A. Such a correspondence doesn't exist between most programming languages and assembly, let alone lambda calculus.
- peterkelly 9y agoExhibit B is still a DSL - just expressed in a syntactic manner that is compatible with C-style programming languages. In your example, each function like cat, or, and range would create an AST node, and you wold pass the result of the expression to an interpreter that executed the regex according to RE semantics. In this sense, the function call mechanism of the host language isn't being used in it's usual sense - that is for actually doing something. Rather, it's a way of declaring an AST similar to S-expressions (though slightly clumsier as you have to define each of these node-creating functions separately).
- kerkeslager 9y ago> Exhibit B is still a DSL - just expressed in a syntactic manner that is compatible with C-style programming languages. True, I suppose. But I think I can agree that you could also call the functions in Exhibit B a library. The difference, in my mind, is that Exhibit B gets you most of the benefits of Exhibit A without most of the implementation difficulty, because it avoids the trap of getting too caught up in syntax over semantics. There is a point where DSLs are used enough that implementing the syntax becomes worth it: there's a reason people implemented SQL and Regex. > In this sense, the function call mechanism of the host language isn't being used in it's usual sense - that is for actually doing something. Eh, I don't know about that. If you recognize that functions can be used in this way, it can quickly become a very powerful tool, even moreso if you're working in a language where those functions can return closures. Lots of code is written in this style. Of course nobody writes these specific functions because most languages support regexes. :)
- QuadrupleA 9y agoAs others have said, regex only works well because you have a sophisticated implementation underneath. SQL is fine and good, but the syntax part is easy - hundreds of ORMs, and LINQ, let you express SQL in native-language syntaxes, e.g.: Select(columns=['fname', 'lname'], table='People', where=Equals('fname', 'bob')) The challenge is in the under-the-hood query optimization, finding the best index to use, caching results in memory, using highly efficient on-disk data structures etc. That stuff is usually written in a procedural language (though it could perhaps be done functionally etc.). So while Racket might make the parsing and transformation to Racket constructs easier, that's just a tiny aspect of making an efficient DBMS. It's not some DSL you'd just cook up anytime you need it. Your hex / photoshop example is about the farthest thing from syntactic sugar imaginable - "syntactic sugar" imples a trivial, usually purely lexical transformation between two ways of expressing something (like the SQL example above).