This page has been proofread, but needs to be validated.
Steele and Sussman
62
The Art of the Interpreter

(DEFINE (EVCOND CLAUSES ENV)
        (COND ((NULL CLAUSES) (ERROR))
              ((EVAL (CAAR CLAUSES) ENV)
               (EVPROGN (CDAR CLAUSES) ENV NIL))
              (T (EVCOND (CDR CLAUSES) ENV))))

(DEFINE (APPLY FUN ARGS)
        (COND ((PRIMOP FUN) (PRIMOP-APPLY FUN ARGS))
              ((EQ (CAR FUN) '&PROCEDURE)
               (EVPROGN (CDDR FUN)
                        (BIND (CADR FUN) ARGS (CADDDR FUN))
                        NIL))
              (T (ERROR))))

For EVAL and EVPROGN see Figure 11.

Figure N8
Treating COND Clauses and Procedure Bodies as Implicit PROGN Forms

Finally, we note that PROGN is unnecessary except as a programming convenience. Because the language is defined to be executed in applicative order (cf. {Note Normal Order Loses} in [Revised Report]), we can force the sequencing of evaluation, as well as throw away unwanted values, by using LAMBDA-expressions. We first note that

(PROGN e1 e2 ... eN-1 eN) ≡ (PROGN e1 (PROGN e2 ... (PROGN eN-1 eN) ... ))

so that we need worry only about PROGN with two subforms:

(PROGN e1 e2) ≡ ((LAMBDA (HUNOZ F) (F))
                 e1
                 (LAMBDA () e2))

(see [Imperative] and [Revised Report]).