Good stuff.
On a Lisp compiler optimization tangent: It’s still relevant to SBCL and also generally interesting so the CMUCL advanced compiler manual section[1] is good reading.
[1] https://cmucl.org/docs/cmu-user/cmu-user.html#Advanced-Compi...
I did a similar thing in opposite order, I compile js to scheme. https://github.com/u9g/js2scheme/blob/main/example.js
Not a serious project, made purely because I had a class that mandated writing scheme for the homeworks.
I think the coolest thing to come out of that project was that I learned that it is possible to convert branching if statements to lisp constructs. That was a fun project :)
Guile scheme has a way to easily see the result of many of these optimisations since they are done on the source level. This means you see the result of inlining, DCE, constant propagation and partial evaluation. Extremely handy and helps even mediocre programmers like myself develop a good understanding of when optimisations are triggered.
Do you check whether constant folding actually results in shorter code? E.g. something like
let a="hello "; b=a++a; c=b++b; in c++c
probably shouldn't be changed into "hello hello hello hello hello hello hello hello "
"Javascript is a Lisp" would definitely be found in the Big Bumper Book of Divisive Things To Say To Programmers alongside its more famous entries, "Tabs or Spaces?", and "Vim or Emacs?".
why
My immediate reaction is that this is as much a semantic mistake as “this message does not exist.”
Maybe I’m wrong, but … well, there it is.
Cool stuff! A suggestion: Avoid the term "dead code elimination". Yes, it is an established term, but it is established as a term for two distinct optimizations.
One form of "dead code" is code that can never be executed:
The other meaning is code that can be executed but computes a value that can never be used: I advise my students to use the terms "unreachable code" and "unused code", respectively.