2.73 Exercise 2.73
We are asked to consider rewriting a procedure for symbolic differentiation, originally written like this:
(define (deriv-1 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))))
so that it uses data-directed programming, like this:
(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 (operand exp) (cdr exp))
The general case is to find operators, which are represented as symbols such as ’+ and exist in pairs with their operands, and dispatch on the entries in the deriv table for differentiating these operations. This means that we can’t dispatch on numbers or variables, because they aren’t pairs with operators and operands.
For example, we could add the entries for taking derivatives of additions or multiplications like this:
(put 'deriv '(+) (lambda (exp var) (make-sum (deriv (addend exp) var) (deriv (augend exp) var)))) (put 'deriv '(*) (lambda (exp var) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))))
We could also add a procedure for constant exponentiation, as per Exercise 2.56:
(put 'deriv '(^) (lambda (exp var) (make-product (make-product (exponent exp) (make-exponentiation (base exp) (- (exponent exp) 1))) (deriv (base exp) var))))
If, however, we instead made tables with the operators as the ops and ’deriv as the type, the opposite of what we do now, we would have to register these differently, swapping the second and third arguments to put and changing the call to get in deriv.
TODO: come back later and test this