Steele and Sussman

46

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) 'LAMBDA)
(LIST '&PROCEDURE (CADR EXP) (CADDR EXP) ENV))
((EQ (CAR EXP) 'SETQ)
(EVSETQ (CADR EXP) (EVAL (CADDR EXP) ENV) ENV))
((EQ (CAR EXP) 'PROGN)
(EVPROGN (CDR EXP) ENV NIL))
((EQ (CAR EXP) 'COND)
(EVCOND (CDR EXP) ENV))
(T (APPLY (EVAL (CAR EXP) ENV)
(EVLIS (CDR EXP) ENV)
ENV))))
(DEFINE (APPLY FUN ARGS ENV)
(COND ((PRIMOP FUN) (PRIMOP-APPLY FUN ARGS))
((EQ (CAR FUN) '&PROCEDURE)
(EVAL (CADDR FUN)
(BIND (CADR FUN) ARGS (CADDDR FUN))))
((EQ (CAR FUN) 'LAMBDA)
(EVAL (CADDR FUN)
(BIND (CADR FUN) ARGS ENV)))
(T (ERROR))))
```

For `VALUE`

, `LOOKUP`

, and `BIND`

see Figure 3.

For `EVCOND`

and `EVLIS`

see see Figure 5.

For `LOOKUP1`

see Figure 10 (not Figure 3).

Figure 14

Interpreter with Both Open and Closed Procedures

Although this is the tradition, it doesn't work very well. The problem is that the lexical variables are not really lexical. Although lexical references cannot incorrectly refer to dynamically intended bindings, the reverse is not true. Dynamic variable references can be captured by bindings intended to be strictly lexical.

For example, we might want to write a procedure which packages up information about dealing with `RADIX`

:

```
(DEFINE (RADIX-10 FUN)
((LAMBDA (RADIX) (FUN))
10.))
```