In the book The Structure and Interpretation of Computer Programs, Section 2.4.3, it says that:
(get <op> <type>)
looks up <op>,<type> entry in the table and returns the item found there.
and apply-generic
is defined as
(define (apply-generic op . args)
(let ((type-tags (map type-tag args)))
(let ((proc (get op type-tags)))
(if proc
(apply proc (map contents args))
(error "No method for these types: APPLY-GENERIC"
(list op type-tags))))))
(map type-tag args)
returns a list but shouldn't get
expect a single symbol as its second argument in (get op type-tags)
?
In the preceding defintion of install-polar-package
you'll see the 'signature' of each these procedures is a list:
...
(put 'real-part '(polar) real-part)
(put 'imag-part '(polar) imag-part)
(put 'magnitude '(polar) magnitude)
...
I.e., in each case '(polar)
, not 'polar
, is put in the table, so to match this we need to pass '(polar)
to get
.
The procedures we are applying at the moment are all unary. real-part
, imag-part
and magnitude
only take one argument. In the next next section, 2.5.1, we insltall procedures that take two arguments and therefore we need to match on two types, e.g, the basic arithmetic operators add
, sub
, mul
and div
:
(put 'add '(scheme-number scheme-number)
(lambda (x y) (tag (+ x y))))
(put 'sub '(scheme-number scheme-number)
(lambda (x y) (tag (- x y))))
(put 'mul '(scheme-number scheme-number)
(lambda (x y) (tag (* x y))))
(put 'div '(scheme-number scheme-number)
(lambda (x y) (tag (/ x y))))
In these cases both the arguments happen to be the same type, but this approach supports procedures with an arbitrary number of arguments of different types.
Comparision of type-tags
to the signature in the table could done with a procedure like equals?
, introduced int Ex 2.54, which tests for structural equality. I.e. that the contents of the two lists are the equivalent.