SICP Exercise 2.56

Question

Show how to extend the basic differentiator to handle more kinds of expressions. For instance, implement the differentiation rule

\[\frac{\partial (u^n)}{\partial x}=nu^{n-1}\frac{\partial u}{\partial x}\]

by adding a new clause to the deriv program and defining appropriate procedures exponentiation?, base, exponent, and make-exponentiation. (You may use the symbol ** to denote exponentiation.) Build in the rules that anything raised to the power \(0\) is \(1\) and anything raised to the power \(1\) is the thing itself.

Answer

We are once again going to make use of our wishful thinking technique here and first simply implement the new version of deriv with no regard for the actual helper function implementations (the newly added part is highlighted):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
(define (deriv exp var)
  (cond ((number? exp) 0)
        ((variable? exp)
         (if (same-variable? exp var) 1 0))
        ((sum? exp)
         (make-sum (deriv (addend exp) var)
                   (deriv (augend exp) var)))
        ((product? exp)
         (make-sum
          (make-product
           (multiplier exp)
           (deriv (multiplicand exp) var))
          (make-product
           (deriv (multiplier exp) var)
           (multiplicand exp))))
        ((exponentiation? exp)
         (make-product
          (make-product (exponent exp)
                        (make-exponentiation (base exp) (- (exponent exp) 1)))
          (deriv (base exp) var)))
        (else (error "unknown expression type: DERIV" exp))))

Then, we can continue by first implementing the exponentiation?, base and exponent helper functions. These are completely analogue to the helpers for make-sum and make-product.

23
24
25
26
(define (exponentiation? x)
  (and (pair? x) (eq? (car x) '**)))
(define (base p) (cadr p))
(define (exponent p) (caddr p))

Finally, we are defining make-exponentiation with the simplification rules as specified in the question.

28
29
30
31
32
33
(define (make-exponentiation r1 r2)
  (cond ((=number? r2 0) 1)
        ((=number? r2 1) r1)
        ((and (number? r1) (number? r2))
         (expt r1 r2))
        (else (list '** r1 r2))))

So, let’s test it with \(x^3\) and see what happens.

(deriv '(** x 3) 'x)

We receive the expected result, since \(\frac{\partial x^3}{\partial x}=3x^2\).

(* 3 (** x 2))