views:

168

answers:

2

I'm forming a class for some work on molecular dynamics as follows:

(defclass %atom (particle)
  ((name :initarg :name :initform (error "Every atom in the system must have a name!"))
   (mass :accessor mass :initarg :mass :initform (getmass name))
   (charge :accessor charge :initarg :charge :initform (getcharge name))))

Initially I thought that I could somehow refer to other slots within the class definition with an initform i.e. (getmass name) - but that turns out to be untrue (or does it?!?). Instead, I'm told that initialize-instance would be the place to put all that initialization stuff... fair enough.

The question I have, then, is when is :initform used? What's the idiomatic preference? I've seen it used as above for generating (error "...") code, and also to initialize default arguments when an :initarg is not provided. But both of those could easily fit into initialize-instance and may make more sense there. Is there a particular way :initform is generally used?

+2  A: 

To complicate things a little bit further, there is also the class option :default-initargs.

Personally I use :default-initargs and :initform as shortcuts when the full power of an after-method for initialize-instance is not needed, and :initform when the slot doesn't have an :initarg.

huaiyuan
+2  A: 

Usually one would use :initform to give a slot some default value. With defclass one can't compute initforms simply based on other slots. There are also other complications, so :initform should be used for simple forms.

Examples

  • set the z slot of a 3d-vector object to 0.0

  • set the list of windows in a screen object to NIL

  • set the 'key function' slot in an object to #'identity

  • set the 'report string' slot in an error to "an error occured"

Any other more complicated set up of slot values should be done in a method. If the object needs to be set up automatically after MAKE-INSTANCE use an :AFTER method to INITIALIZE-INSTANCE.

Rainer Joswig