#lang racket (define (cond? exp) (tagged-list? exp 'cond)) (define (cond-clauses exp) (cdr exp)) (define (cond-else-clause? clause) (eq? (cond-predicate clause) 'else)) (define (cond-predicate clause) (car clause)) (define (cond-arrow-clause? clause) (eq? (cadr (cond-actions clause)) '=>)) (define (cond-arrow-clause-recipient clause) (caddr clause)) (define (cond-actions clause) (if (cond-arrow-clause? clause) (apply (cond-arrow-clause-recipient clause) (cond-predicate clause)) (cdr clause))) (define (cond->if exp) (expand-clauses (cond-clauses exp))) (define (expand-clauses clauses) (if (null? clauses) 'false ; no else clause (let ((first (car clauses)) (rest (cdr clauses))) (if (cond-else-clause? first) (if (null? rest) (sequence->exp (cond-actions first)) (error "ELSE clause isn't last -- COND->IF" clauses)) (make-if (cond-predicate first) (sequence->exp (cond-actions first)) (expand-clauses rest))))))