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

(DEFINE (EVAL EXP ENV)
        (COND ((ATOM EXP)
               (COND ((NUMBERP EXP) EXP)
                     (T (VALUE EXP ENV))))
              ((EQ (CAR EXP) 'QUOTE)
               (CADR EXP))
              ((EQ (CAR EXP) 'COND)
               (EVCOND (CDR EXP) ENV))
              ((EQ (CAR EXP) 'LAMBDA)
               (CONS '&PROCEDURE (CDR EXP)))
              (T (APPLY (EVAL (CAR EXP) ENV)
                        (EVLIS (CDR EXP) ENV)
                        ENV))))

For VALUE see Figure 3.
For APPLY, EVCOND, and EVLIS see Figure 5.

Figure 6
Evaluator for LAMBDA-notation (Dynamically Scoped)

(The reader might have noticed that all EVAL does for a LAMBDA-expression is replace the word LAMBDA with the word &PROCEDURE, and that we could avoid that work by uniformly using LAMBDA instead of &PROCEDURE as the flag for a procedural object. Given then that EVAL on a LAMBDA-expression is an identity operation, we can eliminate the handling of LAMBDA in EVAL merely by requiring the user to write '(LAMBDA ...) instead of (LAMBDA ...). Although the implementors of most LISPs have in fact done just this ever since LISP 1, it is a very bad idea. EVAL is supposed to process expressions and produce their values, and the faCt that it might be implemented as an identity operation is no business to the user. The confusion between a procedural object and an expression having that object as its value will lead to serious trouble. (Imagine confusing 15 with (+ 7 8), and trying to take the car of the former instead of the latter, or trying to add 3 to the latter instead of the former!) The quoted LAMBDA-expression engineering trick discourages the implementation of a referentially transparent LISP. In Part Four we will see the extreme difficulties for a LISP compiler (or other program-understander) caused by the blatant destruction of referential transparency. {Note QUOTE Shafts the Compiler})

The ability to use free variables and local procedures gives us additional freedom to express interesting procedures. For example, we can define a procedure SCALE which multiplies a vector of arbitrary length by a scalar. If the vector is represented as a list of components, then we can use MAPCAR and a local procedure with a free variable: