灯下 登录
计算机科学 / SICP / 2.5.1 Generic Arithmetic Operations

Exercise 2.77 · 习题

Exercise 2.77: Louis Reasoner tries to evaluate
the expression (magnitude z) where z is the object shown in
Figure 2.24. To his surprise, instead of the answer 5 he gets an error
message from apply-generic, saying there is no method for the operation
magnitude on the types (complex). He shows this interaction to
Alyssa P. Hacker, who says “The problem is that the complex-number selectors
were never defined for complex numbers, just for polar and
rectangular numbers. All you have to do to make this work is add the
following to the complex package:”

(put 'real-part '(complex) real-part)
(put 'imag-part '(complex) imag-part)
(put 'magnitude '(complex) magnitude)
(put 'angle '(complex) angle)

Describe in detail why this works. As an example, trace through all the

procedures called in evaluating the expression (magnitude z) where

z is the object shown in Figure 2.24. In particular, how many

times is apply-generic invoked? What procedure is dispatched to in each

case?

练习 2.77:Louis Reasoner 试图对表达式 (magnitude z) 求值,其中 z 是图 2.24 所示的对象。令他惊讶的是,他得到的不是答案 5,而是来自 apply-generic 的错误消息,提示对类型 (complex) 不存在 magnitude 操作的方法。他将这次交互展示给 Alyssa P. Hacker,Alyssa 说:"问题在于,复数的选择函数从未对 complex 数定义过,只对 polar 和 rectangular 数定义了。要让这一切正常工作,只需在 complex 包中加入以下内容:"

(put 'real-part '(complex) real-part)
(put 'imag-part '(complex) imag-part)
(put 'magnitude '(complex) magnitude)
(put 'angle '(complex) angle)

请详细描述这为何有效。以对图 2.24 中的对象 z 求值表达式 (magnitude z) 为例,追踪所有被调用的过程。特别地,apply-generic 被调用了多少次?每次各分派到哪个过程?

Racket #lang sicp
(put 'real-part '(complex) real-part)
(put 'imag-part '(complex) imag-part)
(put 'magnitude '(complex) magnitude)
(put 'angle '(complex) angle)