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)))