[Openmcl-devel] Is this a bug?
Gary Byers
gb at clozure.com
Sat Feb 9 18:21:25 PST 2008
When an object is reinitialized (via REINITIALIZE-INSTANCE with some
initargs), values of slots that aren't denoted by those initargs
don't change.
(defclass example ()
((:x :initarg :x)
(:y :initarg :y)))
#<STANDARD-CLASS EXAMPLE>
? (make-instance 'example :x 17)
#<EXAMPLE #x300040F8C6ED>
? (reinitialize-instance * :y 12)
#<EXAMPLE #x300040F8C6ED>
? (slot-value * 'x)
17
e.g., we didn't say anything about changing the value of the X slot
in that instance, so it didn't change.
The MOP says that DEFCLASS of an existing class uses
REINITIALIZE-INSTANCE to change that class (in-place), with
initargs derived from the defclass form. (CLHS doesn't really
specify what happens when a class is redefined, or at least I
can't find any place where that's specified.)
If the implementation doesn't follow the MOP in this regard,
it might reasonably conclude that the handling of :default-initargs
should be consistent with what happens when a class is being newly
defined. (Or it might conclude something else.) If it does follow
the MOP, the behavior is well-defined but may differ from other
implementations.
I think that this is actually a (near-)FAQ; if the search feature
worked on the mailing lists (crickets chirping), we'd probably find
that it's come up here before; there was some howling on info-mcl a
few years ago when MCL's behavior changed. One side of the argument
might be that the MOP-compliant behavior is good (despite the fact
that it's often an incompatible change and doesn't match informal
expectations) because it's well-specified and predictable; the other
side of the argument might be that an incompatible change like this
(especially when it's counterintuitive) isn't justified by something
as esoteric as the MOP.
On Fri, 8 Feb 2008, Ron Garret wrote:
> ? (defclass foo () ((x :initarg :x :initform 1)) (:default-initargs :x
> 2))
> #<STANDARD-CLASS FOO>
> ? (slot-value (make-instance 'foo) 'x)
> 2
> ? (defclass foo () ((x :initarg :x :initform 1)))
> #<STANDARD-CLASS FOO>
> ? (slot-value (make-instance 'foo) 'x)
> 2
> ?
>
(class-direct-default-initargs (find-class 'foo)) hasn't changed. Doing
(defclass foo ()
((x :initarg :x :initform 1))
(:default-initargs))
is a (possibly somewhat ugly) way of resetting the class's direct
default-initargs to NIL that should work in all implementations.
> SBCL does the same thing, so I'm not sure. CLisp works the way I'd
> expect (returning 1 in the second case).
>
> (What's the rationale behind having both :initform and :default-
> initargs?)
Initargs (whether explicit or defaulted) always affect a slot's
value. Initforms provide values for slots that're otherwise
unbound. (Slots can be made unbound and instances can be
reinitialized, and the distinction between initarg/initform
might be clearer in that case than it is in the case of initializing
a newly allocated instance.)
>
> rg
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>
More information about the Openmcl-devel
mailing list