NextPrevUpTopContentsIndex Example of subclassing

This example is based on that in Complete example of a top-level dspec class.

Define a computed-saved-value object has a function to compute the value the first time:

(defstruct (computed-saved-value (:include saved-value))

saved-value objects are defined using def-computed-saved-value and stored on the plist of their name:

(defmacro def-computed-saved-value (name function)
  `(dspec:def (def-computed-saved-value ,name)
     (when (record-definition `(def-computed-saved-value ,',name)
       (setf (get ',name 'saved-value)
             (make-computed-saved-value :name ',name
                                        :function ,function))

Define a function to compute a computed-saved-value :

(defun ensure-saved-value-computed (name)
  (let ((saved-value (find-saved-value name)))
    (or (saved-value-value saved-value)
        (setf (saved-value-value saved-value)
               (computed-saved-value-function saved-value))))))

Define a macro to access a computed-saved-value :

(defmacro computed-saved-value (name)
  `(ensure-saved-value-computed ',name))

Define a dspec class for def-computed-saved-value dspecs:

(dspec:define-dspec-class def-computed-saved-value def-saved-value
  "Defined computed saved values"
  #'(lambda (name)
      ;; Find any object that def-computed-saved-value recorded
      (computed-saved-value-p (find-saved-value name)))
  ;; The :undefiner is inherited from the superspace.
  #'(lambda (obj)
      ;; Given a computed-saved-value object,  we can reconstruct its dspec
      (and (computed-saved-value-p obj)
           `(def-computed-saved-value ,(saved-value-name obj)))))

For completeness, define a form parser that generates dspecs from forms:

     (:parser dspec:single-form-form-parser)))

Note: this form parser for def-computed-saved-value is not strictly necessary, because the implicit form parser will recognize definitions beginning with "def".

LispWorks User Guide - 11 Mar 2008