Some more progress
This commit is contained in:
		
							
								
								
									
										60
									
								
								sec-2-5.lisp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								sec-2-5.lisp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
;; 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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user