为什么我们不能同化谓词数?和相同的变量?进入数据导向的调度?

Why can't we assimilate the predicates number? and same-variable? into the data-directed dispatch?

section 2.4.3 的练习 2.73 中,显示了以下代码:

(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))

它利用了数据导向的调度,假设对于每个运算符<i>op</i>人们可能会在输入 exp 中找到一个适当的函数 <i>f</i> 已通过 [ 安装在 table 中=58=]put 'deriv op f.

关于这个练习的第一个问题如下

a. […] Why can't we assimilate the predicates number? and variable? into the data-directed dispatch?

其中两个谓词指的是 deriv 的“旧”实现,它使用以下而不是上面的 else 分支:

        ((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))))

我的问题是为什么我不能?

operatoroperands 的拟议实现很简单,假设存在一个运算符,它是表示表达式 exp 的列表中的第一个,所以我可以'不希望在不改变的情况下进行“同化”

但是如果我真的改变了它们呢?

我可以这样定义它们,

(define (operator e)
  (cond ((pair? e) (car e))
        ((number? e) 'number)
        (else 'variable)))

(define (operands e)
  (cond ((pair? e) (cdr e))
        (else e))) ; maybe `e` -> `cons e '()`, not sure

决定如果表达式 e 不是一对,那么 它是 它自己的操作数,运算符是文字 'number'variable 视情况而定。

然后我可以在'deriv-'number'deriv-'variable.

下安装需要的程序

过程 putget 定义在 3.3.3 中,我尽量不超越自己,所以我还没有研究它,因此我还没有按照上面的描述尝试检验我的假设。

你可以这么写,但你还没有真正融入数据导向的方法。您刚刚将 number?variable? 的特殊大小写移动到了不同的函数中。我认为文本是在问你为什么不能在没有任何特殊情况的情况下统一调度 operator,答案是因为你的表示没有为数字或变量定义运算符。

如果我要尝试使这种表示更加统一,我会定义一个构造函数 make-number 以便 (make-number 6) 产生标记为数字的内容,例如 '(number . 6),变量也是如此。 然后您可以为这些标签安装处理程序,只需查看每个数据的运算符,因为每个数据都会有一个运算符。