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

Re: Class Redefinition



     Date: 24 Jul 87  1645 PDT
     From: Dick Gabriel <RPG@sail.stanford.edu>
     Subject: Class Redefinition 
     
     
     The problem with class redefinition is that the updating of instances can
     be caused by arbitrary events, as far as the user is concerned. If none of
     DEFCLASS, ADD-METHOD, MAKE-METHOD, CLASS-NAMED, the evaluation of the
     special form FUNCTION, and garbage collection can update instances, then
     if a CLOS implementation does not have multitasking, the following will
     work (or something like it):
     
     	(let ((obsolete-class (class-named 'heh-heh)))
              (defclass heh-heh ...)
              (add-method 
               #'class-changed
     	  (make-method	;later, make-instance
                ()
                `(,obsolete-class ,(class-named 'heh-heh))
     	   #'...)))

This code is not quite right, the new class object (produce by defclass
heh-heh is the same as the old one (the one you bound to
obsolete-class). [pg 1-11]
The following will work.
(let ((current-class (class-named 'heh-heh)))
   (defclass heh-heh ...)
   (add-method 
      #'class-changed
     (make-method	;later, make-instance
         ()
         `(,(get-obsolete-version current-class) ,current-class)
     	 #'...)))
     
     If there is a CLOS implementation with all of the properties named
     above except it does have multitasking (including incremental GC),
     then some form or macro like ATOMICALLY wrapped around the above
     will work.
Right. However, the CPU time spent in ATOMICALLY can be quite
large, realistically some implementation will not be able to give an
upper bound for its elapsed time from start to completion. If a CLOS
implementation has to make sure that this time is kept short, it will
have to bear yet another constraint that could be avoided.
     
     Something like this should work:
     
     (let
      ((obsolete-class (class-named 'heh-heh))
       (new-class (make-instance 'standard-class ...))) ;make an anonymous class
                                                        ;that is the new HEH-HEH
      (add-method 
       #'class-changed
       (make-method	;later, make-instance
        ()
        `(,obsolete-class ,new-class)
        #'...))
      (name-that-class new-class 'heh-heh))             ;Hm, what is this function?
     
This does not work for the same reason the first example did not work.
However I don't see how to fix this one without resorting to my
proposal. It would go like this:

(let*
     ((current-class (class-named 'heh-heh))
      (obsolete-class (assoc current-class
                             (GET-OBSOLETE-CLASSES-FOR-REDEFINITION
                                 current-class))))
  (add-method 
       #'class-changed
       (make-method	;later, make-instance
        ()
        `(,obsolete-class ,current-class)
        #'...))
  (defclass heh-heh ...))    ;(name-that-class new-class 'heh-heh))

     I think, though, that it probably makes sense to have Danny's version
     of GET-OBSOLETE-CLASS for the same reason that I don't like UNIX - it's
     too easy to do a DEFCLASS of an existing class and then wish you
     had a handle on the old one. I think we need to decide whether Patrick's
     versions of getting obsolete classes are worth having around to simplify
     life.

If you can find another solution to your second example (ie without
using ATOMICALLY), I would be inclined to live with Danny's
proposal.
     
     I think we forgot to define NAME-THAT-CLASS. It should be the thing such
     that MAKE-INSTANCE + (<the thing> <name>) = (DEFCLASS NAME ...).
This thing will be in the metaclass protocol

Patrick.