Skip to content

2.73

; Section 2.3.2 described a program that performs symbolic differentiation:

(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))))
          (else (error "unknown expression type: 
                       DERIV" exp))))

; We can regard this program as performing a dispatch on the type of the expression 
; to be differentiated. In this situation the “type tag” of the datum is the 
; algebraic operator symbol (such as +) and the operation being performed is deriv. 
; We can transform this program into data-directed style by rewriting the basic 
; derivative procedure as

(define (deriv exp var) 
    (cond ((number? exp) 0)
          ((variable? exp) (if (same-variable? exp var) 1 0)) 
          (else ((get 'deriv (operator exp))
                 (operands exp) var)))) 
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))

; (a) Explain what was done above. Why can’t we assimilate the predicates number? 
;     and variable? into the data-directed dispatch?

; Ans:
; number? and variable? do not use any operator or operands. Hence there's no need
; of dispatch method

; (b) Write the procedures for derivatives of sums and products, and the auxiliary 
;     code required to install them in the table used by the program above

; Ans:

(define (deriv-sum exp var)
    (make-sum (deriv (addend exp) var)
              (deriv (augend exp) var)))
(define (deriv-product exp var)
    (make-sum (make-product 
                (multiplier exp)
                (deriv (multiplicand exp) var))
              (make-product
                (deriv (multiplier exp) var)
                (multiplicand exp))))

(deriv (install-deriv)
    (put 'deriv '+ deriv-sum)
    (put 'deriv '* deriv-product)
    'done)

; (c) Choose any additional differentiation rule that you like, such as the one for 
;     exponents (Exercise 2.56), and install it in this data-directed system.

; Ans:
(define (deriv-expo exp var)
    (define b (base exp))
    (define e (exponent exp))
    (make-product
        e
        (make-product
            (make-exp b (make-sum e -1))
            (deriv b var))))

(define (install-expo)
    (put 'deriv '** deriv-expo))

; (d) In this simple algebraic manipulator the type of an expression is the algebraic
;     operator that binds it together. Suppose, however, we indexed the procedures 
;     in the opposite way, so that the dispatch line in `deriv` looked like
;  
;     ((get (operator exp) 'deriv) (operands exp) var)
;   
;     What corresponding changes to the derivative system are required?

; Ans:
; We need to reverse the map
(put '+ 'deriv deriv-sum)
(put '* 'deriv deriv-product)