From: Stig Hemmer
Subject: change-class voes.
Date: 
Message-ID: <ekvww073quq.fsf@gnoll.pvv.ntnu.no>
Greetings.  I'm learning my way around CLOS and am currently writing a
toy example to get my feet wet.

I have a notional class FOO, with two implementations, FOO-BAR and
FOO-BAZ.

FOO-BAR is more efficient than FOO-BAZ, but cannot be used in all
situations.  What I would like to do is to start by making FOO-BAR
instances and CHANGE-CLASS them into FOO-BAZ as needed.

Now, I'm looking at the Hyperspec entry on CHANGE-CLASS and am a bit
confused by the end note:

:The generic function change-class has several semantic
:difficulties. First, it performs a destructive operation that can be
:invoked within a method on an instance that was used to select that
:method. When multiple methods are involved because methods are being
:combined, the methods currently executing or about to be executed may
:no longer be applicable.  Second, some implementations might use
:compiler optimizations of slot access, and when the class of an
:instance is changed the assumptions the compiler made might be
:violated.  This implies that a programmer must not use change-class
:inside a method if any methods for that generic function access any
:slots, or the results are undefined.

The code I want to write looks like this(simplified):

(defclass foo () ())
(defclass foo-bar (foo) (stuff))
(defclass foo-baz (foo) (stash))

(defgeneric add-data-to-foo (this that foo)
  (:documentation "Destructivly add THIS/THAT to FOO."))

(defmethod add-data-to-foo ((this right-type) that (foo foo-bar))
  ... slot-value ...)

(defmethod add-data-to-foo (this that (foo foo-bar))
  (change-class foo 'foo-baz)
  (add-data-to-foo this that foo))

(defmethod add-data-to-foo (this that (foo foo-baz))
  ... slot-value ...)

There are no :BEFORE, :AFTER or :AROUND methods.

Now, this is in conflict with the last sentence of the quoted text
above.  However, I fail to see any problems like those mention in the
rest of this paragraph.  Is the last sentence still qualified by the
"When multiple methods are involved ..." phrase or isn't it?

In short, is this code safe?
If not, how should I approach this problem?

Stig Hemmer,
Jack of a Few Trades.