[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Class redefinition and class-changed.
- To: common-lisp-object-system@SAIL.STANFORD.EDU
- Subject: Class redefinition and class-changed.
- From: Patrick H Dussud <DUSSUD%Jenner%ti-csl.csnet@RELAY.CS.NET>
- Date: Wed, 29 Jul 87 14:58:12 CDT
- In-reply-to: Msg of Sat, 25 Jul 87 01:26 EDT from "David A. Moon" <Moon@scrc-stony-brook.arpa>
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
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
2) believe that these rho and theta methods could be removed from the
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.