:initform and :default-initargs
There are two means of automatic initialization of CLOS slot values, :initform and :default-initargs. Chris Riesbeck makes a strong case for preferring :default-initargs.
Here’s a simplified example of the syntactic difference, taken from some Quicklisp code. Consider modeling version control commands with CLOS. Here’s a possible design:
(defclass vc-command ()
((command
:initarg :command
:accessor command)
(checkout-subcommand
:initarg :checkout-subcommand
:accessor checkout-subcommand)))
To make subclasses for CVS and git, one option is to use the initform slot option:
(defclass vc-git (vc-command)
((command
:initform "git")
(checkout-subcommand
:initform "clone")))
(defclass vc-cvs (vc-command)
((command
:initform "cvs")
(checkout-subcommand
:initform "co")))
I prefer to use :default-initargs to avoid recapping the slots:
(defclass vc-git (vc-command) () (:default-initargs :command "git" :checkout-subcommand "clone")) (defclass vc-cvs (vc-command) () (:default-initargs :command "cvs" :checkout-subcommand "co"))
:default-initargs also need not correspond to slots. They can be used to pass extra arguments to initialization functions like initialize-instance:
(defclass fribble (dibble)
()
(:default-initargs
:persist nil))
(defmethod initialize-instance :after ((instance dibble) &key persist)
(when persist
(persist-object instance)))