This asks about initializing slots from other slots. What I want to achieve instead is to take some arguments as input - perhaps but not necessarily to make-instance - and convert these arguments into the class slots for storage. In effect, I want to separate the implementation of the class from its (initialization) interface.
Is there a recommended way to achieve this?
The simplest way I can imagine is simply create a (defun make-my-object ...) as the interface. This may then call make-instance with appropriate arguments.
For example, imagine
(defclass my-object () (slot-1 slot-2))
(defun make-my-object (arg-1 arg-2)
(make-instance 'my-object
:slot-1 (+ arg-1 arg-2)
:slot-2 (- arg-1 arg-2)))
Other ways I can imagine include implementing an initialize-instance :after that takes arg-1 and arg-2 as keyword arguments and initializes slot-1 and slot-2 appropriately. However, since after methods are called in the least-specific-first-order, that means that superclass slots will be initialized before current-class slot. On the other hand, what looks more common is that one will take arguments for constructing current-class, and on the basis of these arguments, one will initialize the super-class slots.
The alternative is initialize-instance :before - or also :around - but if multiple classes in the hierarchy have such "interface-implementation" differences, I don't see this working, unless I can pass arguments to call-next-method.
Are there other ways?
EDIT: Thanks to @ignis volens for bringing to my notice that (one of) my main concern(s) is about superclass slots being initialized from subclass slots. Is there a recommended way to do this?