Kaz Kylheku
7/30/2015 1:37:00 PM
On 2015-07-30, Jim Newton <jimka.issy@gmail.com> wrote:
> Yes exactly, or I can simply set the slot directly after calling change-class.
> I just seem to always forget this rule. It does not seem correct, but it is
> according to the spec.
You might be thinking that the value of a slot is part of the object's type
in your scheme.
We are changing an A to a B. A B always initializes the slot, and so if that
doesn't happen, then the A to B change is invalid.
But slots values aren't part of the type. Except maybe :allocation :class
slots. That may be the right way to design things.
Suppose we have a tricycle, and tricycle has a wheels slot with a value 3.
We change-class to a car, and cars have wheels slot with value 4.
The change-class will not do anything with this value; so we end up with
a car whose wheels slot is 3.
But the number of wheels is a property of the class, not of the instance.
(Let's assume for this exercise that all cars have four wheels, which is
false).
If we make the wheels slot ":allocation class" in tricycle and car
classes, then that takes care of it.
See what you make of this:
(defclass vehicle ()
((wheels :accessor wheels)))
(defclass tricycle (vehicle)
((wheels :initform 3 :allocation :class)))
(defclass auto (vehicle)
((wheels :initform 4 :allocation :class)))
(defparameter *thing* (make-class 'vehicle))
(wheels *thing*) -> #| error condition: unbound slot |#
(change-class *thing* 'auto)
(wheels *thing*) -> 4 ;; see? unbound slot went to 4 "auto"-magically!
(change-class *thing* 'tricycle)
(wheels *thing*) -> 3 ;; and 4 even changed to 3.
(change-class *thing* 'vehicle)
(wheels *thing*) -> 3 ;; 3 stays as 3 (going from :class to :instance).