6 ms·
Let'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_m
by kerkeslager 9y ago
Let'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. :)
- ohyes 9y agoA recursive descent parser to convert between A and B is trivial. But there are implementation details of functions vs code writing macros that are important. This is not about syntax at all.
- kerkeslager 9y agoIf recursive descent parsers are so trivial, why do we have so many DSLs to generate parsers? :P Also, a recursive descent parser isn't going to spit out an AST that matches the needed NFA/DFA, so there's going to be a transformation step needed.
- heavenlyblue 9y agoDSLs are usually written for domains where the procedural style has dominated for a while already and there’s a concrete set of concepts that have been well researched. So I believe your point is relatively useless: for example, one of the use-cases of a DSL is one’s ability to change the program at run-time , having run time predictions and also the proof of termination - all of which are a sign of a well-behaved product from the customer’s point of view.
- kerkeslager 9y agoThe problem with the claims you're making about DSLs is you're not backing up anything you say with concrete examples where the implementation cost of the DSL is actually worth it. You're not responding to my point. > for example, one of the use-cases of a DSL is one’s ability to change the program at run-time , having run time predictions and also the proof of termination Returning the program as a closure with different values closed at runtime achieves the same theoretical benefit and is supported by a wide variety of popular languages with no cost of implementing the syntax.
- heavenlyblue 9y agoIt does not, however - allow me to re-implement the methods based on the values passed into them. The greatest example of this is SQL: it takes the set of statements and transforms them into a set of steps a database needs to run in order to give you a result (and there are many ways of doing so). So essentially we end up with an optimisation problem that has to be solved (and many problems in computing are the optimisation problems where the question can be answered in many different ways). You could, however - argue that you could also implement an SQL-like language with the language of your choice; but then you had just re-implemented a DSL. And the last point against you is the fact that we are currently at the point where writing plugins for the IDEs is getting more easy, so quite frankly - the overhead of writing a new DSL is becoming less of an issue.
- da_chicken 9y agoYeah, but in that sense, C is "just syntactic sugar" for Assembly. You keep using "syntactic sugar" in a disparaging sense when everything short of machine code essentially qualifies. After all, what is a compiler but a program to strip out and distill the abstractions of using a higher level language into machine code? Like I don't need functions or methods, either, but that doesn't mean that I should avoid their use. Shouldn't I decide when implementing a function or DSL is worth the effort? Yes, it's time consuming, but abstractions provide real value in programming. All you're really saying is "I can implement a regex engine in C." I mean, no shit. But you're implying that means DSLs are somehow inappropriate or unworthy of use because of that. There are big flaws in that logic.
- kerkeslager 9y ago> Yeah, but in that sense, C is "just syntactic sugar" for Assembly. That's not true in anywhere near the same sense. There's not a 1 to 1 correspondence that lets you transform C semantics into assembly. Assembly has no counterpart to C types, for example. And if you recognize that your initial argument is flawed, the rest of what you're saying falls apart. > Like I don't need functions or methods, either, but that doesn't mean that I should avoid their use. If you can point out where I said you should avoid the use of DSLs I'll be very surprised. What I said is that the cost of implementing a DSL is rarely worth it, given a library will often provide 90% of the benefit a DSL with 10% of the effort. > Yes, it's time consuming, but abstractions provide real value in programming. Yep. And functions are an abstraction which has a very low cost in most programming languages and provides. > All you're really saying is "I can implement a regex engine in C." If that's what you think I said, you should read what I said again.
- ohyes 9y agoBoth of these examples would require implementation of a regex engine to provide the same set of functionality. You’ve just given the syntactic sugar next to the ast parse, parsing a regex into an ast representation is fairly easy and can be done with recursive descent (it is trivial). But this is supposed to be about DSLs not parsing, the DSL is either, because you’ve just given the DSL in two different forms. (One with sugar, one without).