<< Previous exercise (4.3) | sicp-solutions | Next exercise (4.5) >>

a.

;; procedures to extract the parts of the expressions (define (and-clauses exp) (cdr exp)) (define (or-clauses exp) (cdr exp)) (define (first-exp seq) (car seq)) (define (rest-exp seq) (cdr seq)) (define (empty-exp? seq) (null? seq)) (define (last-exp? seq) (null? (cdr seq))) ;; (and (list? '()) (number? 2) 3) => 3 (define (eval-and exps env) (cond ((empty-exp? exps) #t) (else (let ((first (eval (first-expt exps) env))) (cond ((last-exp? exps) first) (first (eval-and (rest-exp exps) env)) (else #f)))))) (define (eval-or exps env) (cond ((empty-exp? exps) #f) (else (let ((first (eval (first-exp exps) env))) (cond ((last-exp? exps) first) (first #t) (else (eval-or (rest-exp exps) env)))))))

b.

;; (and (list? '()) (number? 2) 3) ;; derived into "if" ;; (if (list? '()) ;; (if (number? 2) ;; 3 ;; #f) ;; #f) (define (and->if exp) (expand-and-clauses (and-clauses exp))) (define (expand-and-clauses clauses) (cond ((empty-exp? clauses) 'false) ((last-exp? clauses) (first-exp clauses)) (else (make-if (first-exp clauses) (expand-and-clauses (rest-exp clauses)) #f)))) (define (or->if exp) (expand-or-clauses (or-clauses exp))) (define (expand-or-clauses clauses) (cond ((empty-exp? clauses) 'false) ((last-exp? clauses) (first-exp clauses)) (else (make-if (first-exp clauses) #t (expand-or-clauses (rest-exp clauses))))))