Lisp macros make adding HTML syntax easy. You won’t find anyone using string templates in that language because a handful of macros means you can just program like it’s just lisp.
Strings such primarily because they don’t establish regularity. If you don’t understand everything fully and follow their patterns exactly, it’s easy to accidentally lose your pseudo-macro hygiene and output garbage.
JSX was a revelation simply because it was a “macro” (DSL) that ECMA had already designed an entire spec around (E4X) and thoroughly baked into the language. Like with Lisp, you could just use your normal coding patterns to interface.
A custom HTML macro baked into the syntax makes sense in a language where almost everyone using it is going to need HTML. It would make far less sense to dedicate all that syntax space in a more general purpose language.
And in JS, even with all that design time spent on E4X, you are still back to doing string interpolation the second you step away from that specific syntax (or you’re forced to express everything as HTML even if it’s not a good fit).
The world would be a better place if JS had been scheme and people had been forced to learn a lisp.
Another reason you won't find people using string templates to produce HTML in Lisp is that no one uses it for web development. This phenomenon where multiple language features conspire to prevent misuse is called defense in depth and is one of the great strengths of the language.
Ironically, the dominant solution for dynamic HTML in Clojure apps, Hiccup, does not rely on macros as much as it relies on keyword and collection literals.
Reddit apparently ran away from Lisp primarily because all the servers ran on FreeBSD while development ran on Macs and because at the time they were forced to use different Common Lisp implementations (OpenMCL on Mac and CMUCL on FreeBSD) so they couldn't even test what they were deploying, essentially. Today with SBCL that wouldn't have been an issue.
> Another reason you won't find people using string templates to produce HTML in Lisp is that no one uses it for web development
...how does this change conditional probability? If of those people who use Lisp for web development, nobody uses strings, it's unrelated to how many people use Lisp for web development.
> This phenomenon where multiple language features conspire to prevent ~~misuse~~ use is called defense in depth and is one of the great strengths of the language.
Not only do they use it for web development, but they manage to regularly update and upgrade their Lisp based web apps (as opposed to ignoring customer emails because their pile of PHP/Perl is too hairy to debug).
It wouldn't be the same and that would be a GOOD thing.
Chez scheme is probably about as fast as JS JITs and with only a fraction of the time spent creating it. If you restrict continuations, you can get even better performance. On the flip side, new JS features like BigInt would have existed from the start (along with generators, rest/spread, typed arrays, let/const, etc). Features like threads that don't exist probably would exist.
On the better side, all the terrible things people complain about like hoisting, `with`, type coercion, weird prototypal inheritance, bad Java-based dates, etc simply wouldn't have happened because Scheme already specced out most of the relevant things.
HTML would have likely disappeared over time because innerHTML and string parsing would be radically less efficient than just using the macros.
We wouldn't have 10 different versions of JS because most of the new stuff either would have been baked into the first version or could be easily accomplished with macros. Major versions would be little things like adding optional type hints or
CSS wouldn't exist because you'd create sets of styles with lisp lists then pass them in. It would be a better version of CSS in JS, but done 25 years ago.
JSON wouldn't have been discovered because lists do all the things better. Likewise, there wouldn't be a need for the "lost decade" of XML development because those same scheme macros would do that job and transformer macros are far easier and better to write than XSLT.
> all the terrible things people complain about like [...] `with` [...]
I would be fairly surprised to hear someone complain about with-statements. My impression is that most folks don't even know it exists, and I'd be very shocked to see it actually being used in the wild.
Mark Miller (the ocap / promises / E guy) used `with` in the “eight magic lines” implementing realms (i.e. complete isolation) on top of vanilla JS[1]. Other than that, it’s probably effectively unused, but I suspect the mere possibility of it still makes implementors’ lives markedly worse.
> None of the modern web would be around though because we’d still be waiting for a sufficiently advanced compiler.
Huh? This doesn’t make any sense. I don’t think people have done a lot of Scheme JITs, but Scheme has some pretty damn impressive compilers—Chez[1] first and foremost. Certainly ones with better codegen than pre-V8 JavaScript ones. Scheme (the standard fragment) is less dynamic than JavaScript, not more (which has been used as an argument against that fragment by more OG-Lisp-inclined people).
(The one potenial problem I can name is tail calls—IME LuaJIT is much, much worse at compiling Lua’s Scheme-like proper tail calls than it is at the same code expressed as a loop. But then the price for LuaJIT’s small size is that it’s a bit picky at which code it’s willing to compile well. Production JS engines probably handle that better, if at a cost of a couple of orders of magnitude more code.)
JS originally was a scheme, then the syntax got nerfed by managerial diktat and the rest is history. It also went a horrifically long time without a sufficiently advanced compiler. Some (who would immediately grin, duck, and run) would say it still lacks one.
JavaScript has very similar semantics to scheme, and is just as hard to compile. V8 works well due to incredible engineering effort that draws upon scheme compiler research.
The biggest language difference I can think of is the guarantees about numeric types. JS can easily compile to native float or integer operations, when it's hard to do that in scheme.
What other scheme features do you have in mind that make it harder to compile? ( Maybe ignoring call/cc)
Me also. I was there at the birth of E4X as a fresh out of college kid writing test cases for the language. There are some warts in the language but it is still much easier to use E4X than the DOM.
The E4X spec was just bad. There were too many corner cases with very unintuitive behavior or just plain spec bugs. I wish it was E4H focusing on needs of HTML with no xml namespace nonsense. It could have a chance then.
Lisp macros make adding HTML syntax easy. You won’t find anyone using string templates in that language because a handful of macros means you can just program like it’s just lisp.
Strings such primarily because they don’t establish regularity. If you don’t understand everything fully and follow their patterns exactly, it’s easy to accidentally lose your pseudo-macro hygiene and output garbage.
JSX was a revelation simply because it was a “macro” (DSL) that ECMA had already designed an entire spec around (E4X) and thoroughly baked into the language. Like with Lisp, you could just use your normal coding patterns to interface.
A custom HTML macro baked into the syntax makes sense in a language where almost everyone using it is going to need HTML. It would make far less sense to dedicate all that syntax space in a more general purpose language.
And in JS, even with all that design time spent on E4X, you are still back to doing string interpolation the second you step away from that specific syntax (or you’re forced to express everything as HTML even if it’s not a good fit).
The world would be a better place if JS had been scheme and people had been forced to learn a lisp.