sicp-ex-2.88



<< Previous exercise (2.87) | Index | Next exercise (2.89) >>


meterogan

  
 (define (negate x) (apply-generic 'negate x)) 
  
 ;; add into scheme-number package 
 (put 'negate 'scheme-number 
       (lambda (n) (tag (- n)))) 
  
 ;; add into rational package 
 (put 'negate 'rational 
      (lambda (rat) (make-rational (- (numer rat)) (denom rat)))) 
  
 ;; add into complex package 
 (put 'negate 'complex 
      (lambda (z) (make-from-real-imag (- (real-part z)) 
                                       (- (imag-part z))))) 
  
 ;; add into polynomial package 
 (define (negate-terms termlist) 
   (if (empty-termlist? termlist) 
         the-empty-termlist 
         (let ((t (first-term termlist))) 
           (adjoin-term (make-term (order t) (negate (coeff t))) 
                        (negate-terms (rest-terms termlist)))))) 
 (put 'negate 'polynomial 
          (lambda (poly) (make-polynomial (variable poly) 
                                          (negate-terms (term-list poly))))) 
 (put 'sub '(polynomial polynomial) 
       (lambda (x y) (tag (add-poly x (negate y))))) 
          
 (define (negate-terms termlist) 
    (map  
       (lambda (t)(make-term(order t) 
                            (- (coeff t)))) 
        termlist)) 
  
 ;; I got the same idea as hi-artem to use map procedure, however I think we need to use the generic negate for coeff as well 
  
 (define (negate-poly p) 
   (make-polynomial (variable p) 
                    (map 
                      (lambda (term) 
                        (make-term 
                          (order term) 
                          (negate (coeff term)))) 
                      (term-list p)))) 

I think hi-artem is wrong and meterogan is right. Because MAP only works on lists, it is impossible to achieve Abstract masking if MAP is used.However, there are also errors in meterogan's writing.It should look like this:

 ;; add into complex package 
 (put 'negate 'complex 
      (lambda (z) (make-from-real-imag (negate (real-part z)) 
                                       (negate (imag-part z))))) 
  
 (put 'sub '(polynomial polynomial) 
       (lambda (x y) (tag (add-poly x (contents (negate (tag y))))))) 




Totti

I didn't follow the book's suggestion and implemented the sub procedure by adding the terms of the first polynomial to the multiplication of all terms of the second by -1 or -1x^0.

 (define (sub-poly p1 p2) 
       (if (same-variable? (variable p1) (variable p2)) 
           (make-poly (variable p1) 
                      (add-terms (term-list p1) 
                                 (mul-term-by-all-terms (make-term 0 -1) 
                                                        (term-list p2)))) 
           (error "Polys not in same var -- SUB-POLY" 
                  (list p1 p2))))