61 lines
2.2 KiB
Common Lisp
61 lines
2.2 KiB
Common Lisp
;; 2.77
|
|
;; obviously magnitude isn't defined yet on the complex type,
|
|
;; it is only defined in the internal types, i.e. the secondary types.
|
|
;; this means that the first apply-generic will immediately fail.
|
|
;; the reason Alyssa's fix works, is because this makes the
|
|
;; maginute function dispatch to itself when seing the type
|
|
;; '(complex). Then, magnitude will be called with the
|
|
;; internal type - e.g. '(rectangular 3 4), which gives
|
|
;; the correct answer.
|
|
|
|
;; 2.78
|
|
|
|
(defun type-tag (datum)
|
|
(cond
|
|
((consp datum) (car datum))
|
|
((numberp datum) 'number)
|
|
(t (error "unkown type"))))
|
|
|
|
(defun contents (datum)
|
|
(cond
|
|
((consp datum) (cdr datum))
|
|
((numberp datum) datum)
|
|
(t (error "unknown type"))))
|
|
|
|
;; assuming the dispatch function actually calls the function with
|
|
;; the contents of each datum, then you should now be able to just
|
|
;; insert #'+, #'*, #'- and #'/
|
|
|
|
;; 2.79
|
|
|
|
;; 2.81
|
|
;; First, apply-generic is called.
|
|
;; 'exp is not defined on complex numbers. Therefore, the apply-generic
|
|
;; function somewhat mistakenly enters the second branch, and first tries
|
|
;; to find a coercion from the first argument's type to the second argument's
|
|
;; type. It finds this coercion function. But then it calls:
|
|
;; (apply-generic op (t1->t2 a1) a2)
|
|
;; this is a problem, because it now enters an infinite loop. Every time,
|
|
;; apply-generic will try to find the 'exp method, not find it, and try
|
|
;; to coerce the first argument to the second argument's type.
|
|
;; It will succeed, and call itself again.
|
|
;; Since this is a tail call, it will be optimised and this will be reduced
|
|
;; to an infinite loop.
|
|
;;
|
|
;; Something can be done about it. We can simply compare the tags of
|
|
;; the objects before trying to coerce - and we can simply raise an error
|
|
;; if both objects have been coerced to the same type and there is still
|
|
;; no function found. Coincidentally, this would also prevent Louis Reasouner's
|
|
;; previous infinite loop.
|
|
|
|
|
|
|
|
;; In order to be extra spicy, I will be completing the exercises in
|
|
;; the symbolic algebra section through the use of CLOS.
|
|
;; I.e. I will actually build an AST of these objects, and use
|
|
;; methods to parse, interpret and modify them.
|
|
|
|
;; Tomorrow. I will do that tomorrow.
|
|
|
|
|