On Wed, Jan 5, 2011 at 7:17 AM, Didier Verna didier@lrde.epita.fr wrote:
Until now, I've been uncounsiously relying on something that the standard does not seem to specify: the fact that shared slots equipped with an initform are initialized before the first instance is created:
(defclass test () ((slot :allocation :class :initform t)))
(defmethod initialize-instance :before ((test test) &key) (format t "Slot boundp: ~A~%" (slot-boundp test 'slot)))
- (make-instance 'test)
Slot boundp: T
- (make-instance 'test)
Slot boundp: T
I just realized that because with ABCL (and contrary to the other implementations I've tried), the result is NIL, and then T.
But now, I'm a little confused. Section 7.1.3 of CLHS says:
An :initform form is used to initialize a slot only if no initialization argument associated with that slot is given as an argument to make-instance or is defaulted by :default-initargs.
So after re-reading this (the "only" part notably), it now appears to me somewhat abusive to initialize shared slots earlier than at first instance creation time (like most lisps seem to do), because there's no way to know, at that time, whether the fist call to make-instance will provide an initarg.
WDYT?
It's possible that the CLHS is not perfectly consistent on this point, but there are a couple of places where it endorses the familiar interpretation. In section 7.1 it says: "The :initform for a shared slot may be used when defining or redefining the class." On the DEFCLASS page it says "... for shared slots, the dynamic environment [to be used when evaluating the :initform form] is the dynamic environment in which the defclass form was evaluated."
I think the sentence from 7.1.3 that you've quoted is intended to apply only to local slots; I think these other two passages make that clear by establishing that shared slots are indeed initialized at defclass time.
Oh, and this appears to be a bug in ABCL, since the second passage I quoted above _requires_ the :initform to be evaluated at defclass time.
-- Scott