乐正

Actions speak louder than words.

Sicp-ex2-77

问题

Louis Reasoner试着去求值(magnitude z),其中的z就是图2-24里的那个对象。令他吃 惊的是,从apply-generic出来的不是5而是一个错误信息,说没办法对类型(complex) 做操作magnitude。他将这次交互的情况给Alyssa P. Hacker看,Alyssa说:“问题出在你 没有为complex数定义复数选择函数,而只是为polar和rectangle数定义了它们。你需要做的 就是在complex包里加入下面这些东西。”:

1
2
3
4
(put 'real-part '(complex) real-part)
(put 'imag-part '(complex) imag-part)
(put 'magnitude '(complex) magnitude)
(put 'angle '(complex) angle)

请详细说明为什么这样做是可行的。作为一个例子,请考虑表达式(magnitude z)的求值 过程,其中z就是图2.24里展示的那个对象,请追踪一下这一求值过程中的所有函数调用, 特别是看看apply-generic被调用了几次?每次调用中分派的是哪个过程?

解答

z值的数据结构如下:

1
'(complex rectangular (3 4))

其第一层标志是complex,而包中并没有magnitude操作。是求值(magnitude z)时的 调用过程如下:

1
2
3
4
5
6
7
(magnitude '(complex rectangular (3 4))                 ;=>
((get 'magnitude 'complex) '(complex rectangular (3 4)) ;=>
(apply-generic 'magnitude '(rectangular (3 4))          ;=>
((get 'magnitude 'rectangular) '(rectangular (3 4))     ;=>
(magnitude '(3 4)                                       ;=>
(sqrt (+ (sqrt (real-part '(complex rectangular (3 4))
         (sqrt (imag-part '(complex rectangular (3 4))

整个过程中只应用了一次apply-generic过程。

draft

« sicp-ex2-76 sicp-ex2-78 »

Comments