An analogy I like is - <i>Are Perl-style regexes (used in Python, Ruby, Java, .NET, etc.) syntactic sugar for regular languages?</i><p>The answer is no, because Perl added all sorts of imperative doodads to regexes, which can’t be easily represented and executed in the automata-based paradigm. Trying to do this is like a “research paper generator” (and not in a bad way), e.g.<p><i>Derivative Based Nonbacktracking Real-World Regex Matching with Backtracking Semantics</i> - <a href="https://dl.acm.org/doi/abs/10.1145/3591262" rel="nofollow">https://dl.acm.org/doi/abs/10.1145/3591262</a> (2023)<p>This is until Go and Rust, which used automata-based regexes from the beginning. I don’t think users have lost much.<p>Purely automata-based engines are kind of pleasant to write, because almost everything is in the compiler, and not in the runtime, e.g. <a href="https://github.com/andychu/rsc-regexp/blob/master/py/README.md">https://github.com/andychu/rsc-regexp/blob/master/py/README....</a><p>That is, features like ? + * really are syntactic sugar for repetition. There’s also a lot of syntax sugar around character classes like [^a], and the runtime is very small.<p>---<p>Likewise, SQL seems to have so many non-relational doodads in its language design, which cause problems for implementers. In this case, I think there’s an incentive problem with SQL: It benefits vendors if their dialect is harder to re-implement. Although certainly they’ve added many useful features too in 4-5 decades!<p>To me a language design issue is we never really “learned” to compose languages with different paradigms:<p>- the set-based paradigms like relational algebra and regular languages, with<p>- Turing-machine like code. (and also I/O!)<p>We never learned polyglot programming, so each language becomes its own source of “reckless growth” – its own parochial backwater.<p>Both regexes and SQL should be able to “escape” to normal code, and that would greatly simplify them. This can be done both by language implementers and by application programmers, i.e. “factoring” across languages. It’s not always obvious how to do this, but it certainly it can be done more than we do it today.<p>---<p>I’d argue the same phenomenon – lack of language composition – leads to programming languages within YAML. Github Actions is nominally some kind of “declarative” scheduler specification, or graph (job -> job dependencies), but that’s not enough for many problems.<p>So it also has a bunch of doodads for escaping that model (to the extent it has a model).<p>Shell, Awk, and Make also grew many doodads (<a href="https://www.oilshell.org/blog/2016/11/14.html" rel="nofollow">https://www.oilshell.org/blog/2016/11/14.html</a>), which are not very well designed. They used to be declarative languages, but no longer are.<p>Although there is some distinction between “formerly set-based languages” like SQL and regex, and other “declarative” non-Turing-complete languages. But I think the language composition problem is approximately the same. Part of it is syntax, but a lot of it is semantics.<p>(copy of lobste.rs comment)