sicp-ex-4.4



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