Comment by nils-m-holm

5 years 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

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.