One form of "dead code" is code that can never be executed:
if (false) {
someDeadCode; // "dead"
}
The other meaning is code that can be executed but computes a value that can never be used: x = someValue;
y = someOtherValue; // "dead"
return x;
I advise my students to use the terms "unreachable code" and "unused code", respectively.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...
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 :)
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 "However, this is a very relevant point. If the goal is just shorter code (as opposed to a mix of shorter code and less run-time operations), then you need to check that folding strings (and similar types) actually makes the expression shorter to represent.
Common Lisp has load-time-value. It's also easy to write a macro called macro-eval which evaluates its argument at macro time, and substitutes the result (as a quoted object).
Maybe I’m wrong, but … well, there it is.
Any situation in which these behaviors cannot be ruled out (because the object escapes beyond the scope of analysis), the optimization cannot be applied.
The spec indeed goes through some trouble to ensure they are pure value-types and do not exhibit any reference-like semantics, for instance by prohibiting their use as keys of WeakMaps and WeakSets - along with numbers, booleans, nullish values, and bignums.