SICP Exercise 2.77 magnitude

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?

SOLUTION

The code and tests are here.

We can see that Alyssa's suggestion works. To understand why, note that the procedure "magnitude" is a generic procedure. It only calls 'apply-generic' with op = 'magnitude and passes on the data object to it. "apply-generic" retrieves the first tag from the data object which happens to be 'complex and looks up the op-table using 'magnitude and '(complex).

But the op-table points back to the same "magnitude" procedure. So "magnitude" is called again - only this time with the same data object with the first tag stripped off.  "magnitude" calls 'apply-generic' with op = 'magnitude and passes the (now) rectangular data object to it. This time around, "apply-generic" retrieves the first tag from the data object which is 'rectangular and looks up the op-table using 'magnitude and '(rectangular). The op-table points to 'magnitude-rectangular' which is the procedure that implements "magnitude" inside the rectangular package.

To summarize, the call sequence is:

magnitude --> apply-generic --> get --> magnitude --> apply-generic --> get --> magnitude-rectangular

"apply-generic" is invoked twice
The first time it dispatches back to "magnitude"
The second time it dispatches to "magnitude-rectangular"

Comments

Popular posts from this blog

SICP Exercise 2.56 differentiation rule

SICP Exercise 1.28 (Miller-Rabin Test)

SICP Exercise 4.18 a alternative strategy for interpreting internal definitions