3 ms·
Early LISP history is a bit blurry, and ancient implementations are full of surprises! Of course, the FUNARG problem was solved in theory in the LISP 1.5 manual
by nils-m-holm 6y ago
Early LISP history is a bit blurry, and ancient implementations are
full of surprises! Of course, the FUNARG problem was solved in theory
in the LISP 1.5 manual, but, as you noted, at the cost of linear symbol
lookup. This is probably the reason why this solution never made it into
the actual implementation. Lexical scoping in combination with shallow
binding did not even appear on the horizon before the LTU papers were
published. Program performance was important on machines operating in
the 200k instructions per second range and lexical scoping appeared to
be expensive (it is, compared to dynamic scoping).
TCE was also a non-issue before the LTU papers, because it was (1) not
necessary, you could just use a tag body, and (2) impossible to get right
with dynamic scoping. Either you unbind after tail-calling and get no TCE,
or you unbind before tail-calling and get a FUNARG problem.
If you want to experiment with LISP 1.5, there are 709 emulators out
there, complete with original LISP tapes.
E.g.: http://www.cozx.com/dpitts/ibm7090.html http://www.cozx.com/dpitts/ibm7090.html
Be prepared for some weirdness, though! Programs are entered as
CONS (FOO BAR)
meaning (CONS (QUOTE FOO) (QUOTE BAR)), there are no comments, and
in-situ lambda functions do not work. For instance,
(LAMBDA (X) X) (FOO)
will evaluate, but
DEFINE (( (TEST (LAMBDA (Q) ((LAMBDA (X) X) Q))) ))
TEST (FOO)
will not. It is fun to explore, though.