2.77 Exercise 2.77
We’re evaluating the expression (magnitude z), where z is equal to ’(complex (rectangular (3 4))). Earlier, the procedure magnitude was defined like this:
(define (magnitude z) (apply-generic 'magnitude z))
As is, this call wouldn’t work because there is no entry in the table for the magnitude operation on the complex type – that is, for the type wrapping the rectangular and polar types we created earlier. However, all we need to do to fix this is to install the magnitude procedure itself as the entry for this type, as so:
(put 'magnitude '(complex) magnitude)
With this in place, the call to magnitude can be expanded like this (I’ve simplified some of the steps for readability):
(magnitude '(complex (rectangular (3 4)))) (apply-generic 'magnitude '(complex (rectangular (3 4)))) (apply (get 'magnitude (type-tag '(complex (rectangular (3 4))))) (contents '(complex (rectangular (3 4))))) (apply (get 'magnitude 'complex) (contents '(complex (rectangular (3 4))))) (apply (get 'magnitude 'complex) '(rectangular (3 4))) (apply magnitude '(rectangular (3 4))) (apply-generic 'magnitude '(rectangular (3 4))) (apply (get 'magnitude (type-tag '(rectangular (3 4)))) (contents '(rectangular (3 4)))) (apply (get 'magnitude 'rectangular) (3 4))
apply-generic gets called twice, or once for each layer of typing our generic complex object has. In the first call, magnitude dispatches to itself, and in the second call, the procedure for the given type of the object (in this case, rectangular).