SICP Exercise 2.73 a (dispatch for symbolic differentiation)
Exercise 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))))
<more rules can be added here>
(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 same-variable? into the data-directed dispatch?
Answer:
The conditional statements in the original implementation have been replaced with the
dispatch method in which the type of arithmetic operation (+, * or **) is used as a key to
index into the table of operations/procedures, and the found procedure is called with the
arguments it expects. This is data-directed programming applied to different 'deriv'
procedures that implement the rules of differentiation and calling the correct one using
the entries in the table.
The table of operations is this:
-------------------------------------------------------------------------------
| + | * | ^
-------------------------------------------------------------------------------
deriv | deriv-of-sum | deriv-of-product | deriv-of-exponentiation
-------------------------------------------------------------------------------
We cannot assimilate number? and same-variable? because the structure of this procedure allows for
dispatches based on specific operators like +, *, ** etc. The dispatch process depends on the call to
the procedure named 'operator' which expects the first element in the list to be an operator. Moreover, it
expects 'exp' to be a pair. But exp may be a number or just a variable in which case it will not be a pair.
So number? and same-variable? need to be handled before the dispatch happens
(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))))
<more rules can be added here>
(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 same-variable? into the data-directed dispatch?
Answer:
The conditional statements in the original implementation have been replaced with the
dispatch method in which the type of arithmetic operation (+, * or **) is used as a key to
index into the table of operations/procedures, and the found procedure is called with the
arguments it expects. This is data-directed programming applied to different 'deriv'
procedures that implement the rules of differentiation and calling the correct one using
the entries in the table.
The table of operations is this:
-------------------------------------------------------------------------------
| + | * | ^
-------------------------------------------------------------------------------
deriv | deriv-of-sum | deriv-of-product | deriv-of-exponentiation
-------------------------------------------------------------------------------
We cannot assimilate number? and same-variable? because the structure of this procedure allows for
dispatches based on specific operators like +, *, ** etc. The dispatch process depends on the call to
the procedure named 'operator' which expects the first element in the list to be an operator. Moreover, it
expects 'exp' to be a pair. But exp may be a number or just a variable in which case it will not be a pair.
So number? and same-variable? need to be handled before the dispatch happens
Comments
Post a Comment