4.5 Exercise 4.5
The most natural place to add support for the alternate form
is in expand-clauses. In the alternate case, we
reformulate the generated code to be an if expression
wrapped in an immediately-invoked lambda (since we
won’t have let expansion until the next exercise), so
we can reuse the computed value if it turns out to be truthy.
(define (expand-clauses clauses) | (if (null? clauses) | 'false | (let ((first (car clauses)) | (rest (cdr clauses))) | (cond ((cond-else-clause? first) | (cond ((cond-alternate-form? first) | (error "ELSE clause isn't allowed in alternate form" clauses)) | ((null? rest) (sequence->exp (cond-actions first))) | (else (error "ELSE clause isn't last -- COND->IF" clauses)))) | ((cond-alternate-form? first) | (let ((rest-expanded (expand-clauses rest))) | (list (make-lambda '(v f) (list (make-if 'v '(f v) rest-expanded))) | (cond-predicate first) | (cond-alternate-form-proc first)))) | (else | (let ((rest-expanded (expand-clauses rest))) | (make-if (cond-predicate first) | (sequence->exp (cond-actions first)) | rest-expanded))))))) |
|
We also rely on the following helper procedures:
(define (cond-alternate-form? clause) | (eq? (car (cond-actions clause)) '=>)) |
|
(define (cond-alternate-form-proc clause) (cadr (cond-actions clause))) |