There was a problem when proofreading this page.
Steele and Sussman
14
The Art of the Interpreter

PROCEDURES symbol table, but variables are bound in ENV. Moreover, in the call to MAPCAR, SQUARE is used as a variable, which is looked up in ENV, but its definition is only available in PROCEDURES.

Let's merge the two symbol tables... How could that hurt?

(DEFINE (DRIVER-LOOP-1 ENV FORM)
        (COND ((ATOM FORM)
               (DRIVER-LOOP ENV (PRINT (EVAL FORM ENV))))
              ((EQ (CAR FORM) 'DEFINE)
               (DRIVER-LOOP (BIND (LIST (CAADR FORM))
                                  (LIST (LIST '&PROCEDURE (CDADR FORM) (CADDR FORM)))
                                  ENV)
                            (PRINT (CAADR FORM))))
              (T (DRIVER-LOOP ENV (PRINT (EVAL FORM ENV))))))

For DRIVER-LOOP see Figure 1.
For EVAL see Figure 5.
For BIND see Figure 3.

Figure 4
Modified Driver Loop for Treating Procedures as Objects

We will eliminate PROCEDURES, and use ENV to contain both procedures and other objects. The driver loop requires no particular changes (see Figure 4), except for eliminating the argument '() in the calls to EVAL. We will change the name PROCEDURES to ENV throughout as well, but of course that isn't logically necessary, because our language is referentially transparent. (Snicker!) {Note EVALQUOTE}

(We have introduced a funny object &PROCEDURE which we use to flag procedural objects. In the previous interpreter it was impossible for the user to request application of an object which was not either a primitive operator or a procedure produced by a DEFINE form. Now that procedures mingle freely with other data objects, it is desirable to be able to distinguish them, e.g. for error checking in APPLY. We also have some deeper motivations having to do with avoiding the confusion of a procedure with its textual representation, but we do not want to deal with this issue yet.)

To fix up the evaluator, we eliminate all occurrences of PROCEDURES. In EVAL, where the name of a procedure in a combination is looked up, we change it to perform the lookup in ENV. Finally, there is a problem in APPLY: if the call to EVAL to evaluate the body is simply

(EVAL (CADDR FUN)
      (BIND (CADR FUN) ARGS '()))

then the new ENV given to EVAL does not have the procedure definitions in it. Moreover, APPLY does not even have access to an environment which