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。
所以,我们只需要修改 augend 和 multiplicand,当取被加数和被乘数的时候,我们主动为其加上 + 和 * 就可以让 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))