Exercise 4.5. Scheme allows an additional syntax for cond clauses, ( => ). If evaluates to a true value, then is evaluated. Its value must be a procedure of one argument; this procedure is then invoked on the value of the , and the result is returned as the value of the cond expression. For example (cond ((assoc 'b '((a 1) (b 2))) => cadr) (else false)) returns 2. Modify the handling of cond so that it supports this extended syntax. ———————————————————————————————————————————————————————————————————————— For the reasons similar to those in Exer. 4.4, this also cannot easily be implemented as a derived form using if. If we do so, either the test will be evaluated more than once, or the generated expression will need to contain a new binding, which we cannot add arbitrarily. Instead we can implement cond as a special form, and add a test and selectors for cond clauses containing arrows. (define (eval exp env) (cond ... ((cond? exp) (eval-cond exp env)) ...)) (define (cond-arrow-clause? clause) (eq? (cadr clause) '=>)) (define (cond-arrow-predicate clause) (car clause)) (define (cond-arrow-procedure-expr clause) (cddr clause)) (define (eval-cond exp env) (eval-cond-clauses (cond-clauses exp) env)) (define (eval-cond-clauses clauses env) (if (null? clauses) false (let ((first (car clauses)) (rest (cdr clauses))) (cond ((cond-else-clause? first) (if (null? rest) (eval-sequence (cond-actions first) env) (error "ELSE clause isn't last" clauses))) ((cond-arrow-clause? first) (let ((result (eval (cond-arrow-predicate clause) env))) (if result (let ((procedure (eval (cond-arrow-procedure-expr clause) env))) (apply procedure result)) (eval-cond-clauses rest env)))) (else (if (cond-predicate first) (eval (sequence->exp (cond-actions first))) (eval-cond-clauses rest env)))))))