[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