SICP 全笔记

Exercise 2.57. Extend the differentiation program to handle sums and products of arbitrary numbers of (two or more) terms. Then the last example above could be expressed as

(deriv '(* x y (+ x 3)) 'x)

Try to do this by changing only the representation for sums and products, without changing the deriv procedure at all. For example, the addend of a sum would be the first term, and the augend would be the sum of the rest of the terms.

因为我们已经有了基本的对 sum 和 product 的处理,所以新的 sum 和 product 可以转为化之前的 sum 和 product 的重复使用:

(new-sum 1 2 3) ;=> (old-sum 1 (old-sum 2 3))

这样做可以不必修改 deriv

所以,我们只需要修改 augendmultiplicand,当取被加数和被乘数的时候,我们主动为其加上 +* 就可以让 deriv 像以前一样处理加法和乘法。

(load "differentiation.scm")

(define (augend s)
  (if (> (length s) 3)
      (cons '+ (cddr s))
      (caddr s)))

(define (multiplicand m)
  (if (> (length m) 3)
      (cons '* (cddr m))
      (caddr m)))


;;; tests begin
(load "../testframe.scm")

;; regression tests
(assert= (deriv '(+ x 3) 'x) 1)

(asserteq? (deriv '(* x y) 'x) 'y)

(assertequal? (deriv '(* (* x y) (+ x 3)) 'x)
              '(+ (* x y) (* y (+ x 3))))

;; new tests
(assertequal? (deriv '(* x y (+ x 3)) 'x)
              '(+ (* x y) (* y (+ x 3))))

(assertequal? (deriv '(+ x (* x 1) x x x) 'x) 5)

;(assertequal? (deriv '(* x x x x) 'x)
;              (deriv '(* x (* x (* x x))) 'x))