Object Initialization and Printing

make-instance → allocate-instance + initialize-instance → shared-initialize Re-initialization with new initargs After a class is redefined After change-class

Printing (print, format ~a/~s, the REPL) Saving instances as literals in compiled files

(defclass circle ()
  ((radius :initarg :radius :initform (error "Radius required") :reader radius)
   (area :reader area)))

;; initialize-instance :after is the standard hook for computed slots and validation
(defmethod initialize-instance :after ((c circle) &key)
  (when (minusp (radius c))
    (error "Radius must be non-negative"))
  (setf (slot-value c 'area) (* pi (radius c) (radius c))))

(area (make-instance 'circle :radius 2))   ; 12.566370614359172d0

;; Custom printing
(defmethod print-object ((c circle) stream)
  (print-unreadable-object (c stream :type t :identity nil)
    (format stream "r=~a" (radius c))))
(make-instance 'circle :radius 1)          ; #<CIRCLE r=1>

;; Constructors: wrap make-instance in a function
(defun make-circle (r) (make-instance 'circle :radius r))

;; shared-initialize / reinitialize-instance / update-instance-for-different-class are further hooks
(defmethod reinitialize-instance :after ((c circle) &key)
  (setf (slot-value c 'area) (* pi (radius c) (radius c))))