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))) |