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

Class redefinition and class-changed.

     We have our choice of three ways to define what happens when a class is
     (1) A new class object is created, the name-to-class-object mapping is
     changed, defclass-defined methods implied by the new definition are put on
     the new class object, all methods other than defclass-defined methods that
     apply to the old class are made to apply also to the new class, subclasses
     of the old class are made to be subclasses of the new class instead, and
     superclasses of the old class are made to be also superclasses of the new
     class.  If we had done this, there would have been an explicit
     representation of versions of a class, and there would not have been any
     concept of "obsolete classes."

I don't like this one for the reasons Gregor and Danny gave.

     This means that -both- arguments to CLASS-CHANGED could be instances of
     obsolete classes.  It also means that our CLASS-CHANGED method can't
     specialize its second parameter, because at first that will be the class
     FOO, but after FOO is redefined again, it will be an obsolete class.  If we
     don't specialize the second parameter, it seems we could be confused by
     CLASS-CHANGED being called when CHANGE-CLASS was used to change an instance
     of FOO into an instance of BAR.  This is not a problem if CHANGE-CLASS,
     like all other generic functions, first updates its argument to the latest
     definition of its class, before changing it to the new class; then a method
     specialized to an obsolete class in its first parameter can never be called
     with the second parameter an instance of anything other than the next newer
     version of the same class.  This all seems slightly kludgey, but does seem
     like it should work.

I like this approach the best because it is more object oriented than
the third one and seems more modular.  However it has the problem Danny
mentioned about applicable methods: 
     I think we have only two choices with respect to methods applicable to
     obsolete instances--
     1) All methods applicable to the class itself i.e. the obsolete-class is
     a subclass of the new class
     2) Only slot-value-using class.
     A problem with the first is what happens if a method is removed from a
     class before an obsolete instance is converted to a real instance.  For
     example, in the famous rho-theta example, suppose we have x-y points
     (ones with x and y as slots), and decide to change class to store only
     rho and theta.  Then after redefining the class, a naive user might 
     1) build a class-changed method that used the methods for rho and theta
     for conversion
     2) believe that these rho and theta methods could be removed from the
     rho-theta-point class.
     In this description I have made it obvious why this is wrong.  But
     suppose this were a case where both of generic functions for rho and
     theta used another routine that was no longer needed.  The user might
     easily delete that one. 
     I think that it might be better to go to 2, though clearly it makes
     class-changed have a lot less easily accessible power.

I don't like danny's 1) because as he shows, it does not work. I don't
like 2) because it breaks modularity. You have to know if an accessor
is implemented as a physical slot access and if not, you have to know
what the accessor was doing. This knowledge is contained in your class
and its superclasses.
How about this one?
 1b)All methods applicable to the class itself at the time of the
It would be up to the implementation to choose the best way of doing
     The third way to define what happens when a class is redefined, mentioned
     earlier, is as follows:  Don't try to use CLASS-CHANGED for both changing
     the class of an instance and updating an instance to a new version of its
     class.  Invent a new generic function CLASS-REDEFINED, which is called when
     an instance is updated to a new version of its class.  This avoids the
     complicated concept of "obsolete classes", at the cost of conveying the
     former state of the instance in a less object-oriented fashion.  Perhaps
     CLASS-REDEFINED would receive three arguments: an instance of the class,
     already updated to the latest definition of the class, a property list
     associating slot names to slot values, with one entry for each slot that is
     no longer present, and a list of slot names of slots that were newly added
     to the instance.  Thus when a class is redefined:
     (3) The old class object is modified, defclass-created methods that aren't
     created by the new defclass are removed, new defclass-created methods are
     added, and the modification is propagated to subclasses.  This is simpler
     than (1) or (2).

The third way is simpler indeed. My main objection to this is that
CLASS-REDEFINED methods have to know all about the implementation of the
class and superclasses (physical slots and methods) AND the whole story
about the successive redefinitions.