[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Function redefinitions shadow types, #<compiled +> wrongly included in labdmda.



Hello all,

I am attempting to extend lisp to operate on images as well as
numbers, all done in a private package (say the IMAGE package).  I am
having a couple of problems with doing this in AKCL 1.605 not present
in Lucid or CmuCL (they have their own problems).

SIN, COS, >, <, +, -, etc. etc. are redefined as functions in the
IMAGE package and declared as shadowed. The new functions examine the
argument list is to see if an image object is present, and if not the
original function is applied to the arglist.  This works surprisingly
well.

However. 

I originally had a macro that takes an operation and builds the
appropriate function:

(defmacro make-arithmetic-list-operation (operation specialized-image-operation)
    
  (let 
      ((original-function 
	(symbol-function (find-symbol (symbol-name operation) 'lisp))))
    
    `(setf (symbol-function ',operation)  
      '(lambda (&rest args)	  
	(let ((images? (mapcar #'internal-image-p args)))
	  (cond
	    ((member t images?)  ;; we have at least one image
	     ... lots-of-stuff ...
	     image-to-return)
	    ;; else, we let the original function handle it.		     
	    (t               
	     (apply ,original-function  args))))))))

Then I would do:

  (make-arithmetic-list-operation + image-+)

This did not work in a compilation environment because KCL inserted a
function definition such as #<compiled lisp::+> in the place of
``original-function''. Since #< > forces an error when read, I could
not compile the new +.  This works OK in LUCID and CMUCL -- is this
just dumb luck on my part, or is KCL in error?  The work-around I
adopted was to use (gentemp) to create an symbol to hang the old
function on:

  (let* 
      ((original-function 
	(symbol-function (find-symbol (symbol-name operation) 'lisp)))
       (original-function-new-symbol 
	(gentemp "OLD-LISP-FUNCTION-")))

    (setf (symbol-function original-function-new-symbol) original-function)

    `(setf (symbol-function ',operation)  
      '(lambda (&rest args)	  
	....
	;; else, we let the original function handle it.
	(t           
	 (apply #',original-function-new-symbol  args))))))))

   -- ASIDE --
This causes it's own headaches on compilation vs. loading -- the
gentemp'd symbols created in the compilation environment are
unavailable when .o files are later loaded into a fresh lisp (I cannot
actually get the redefined arithmetic functions to compile with
compile-file since if the macro above has a call to (compile nil ...
'(lambda ...))  in it I get a recursive-compilation error when the
compiler hits the (make-arithmetic-list-operation +) in the file.
Thus any ``+'' used in the file after the redefinition does not have
the gentemp'd symbols dereferenced into the lisp::+ compiled code.
Yet I need to be able to compile files for later loading into a fresh
lisp, which seems to be impossible.  I have tried various flavors of
(eval-when) around various parts of code but have not hit the right
combination.  Your suggestions are solicited :)
 -- END OF ASIDE --

My other possible bug. It comes about when I redefine COMPLEX and
FLOAT (to turn images into complex images and float images).  This
turns out to break coercion of the *types* complex and float (e.g.,
(coerce 0 'complex) fails), due to the following function in the SI
package:

(defun known-type-p (type)
  (when (consp type) (setq type (car type)))
  (if (or (member type
                  '(t nil null symbol keyword atom cons list sequence
                    number integer bignum rational ratio float
                    short-float single-float double-float long-float complex
                    character standard-char string-char
                    package stream pathname readtable hash-table random-state
                    structure array simple-array function compiled-function))
          (get type 'is-a-structure))
      t
      nil))

COERCE calls the above function (I suppose) which does not find
IMAGE::COMPLEX symbol on the list of types (the new function COMPLEX
is shadowing it).  This seems to me a bug in KCL.  I had hoped
some new type hackery in the IMAGE package would work:

        (deftype complex (&optional component-type)
	  (if (eq component-type '*)                  
	      `lisp::complex
	      `(lisp::complex (,component-type))))

        (deftype float ()
	  `lisp::float)

would fix it (it does interpreted), but I can't get the compiler to
swallow it, either before the shadowed declarations (compiler goes into
infinite loop) or after the complex and float redefinitions (compiler
seems to misinterpret lisp::complex). Any suggestions for work arounds
would be greatly appreciated.

							Thanks,
							Randy Fischer


         Randy Fischer \/ (904) 392-3210
  fischer@math.ufl.edu /\ Dept of Mathematics, Univ of Fl, Gainesville FL 32611