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

function)

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

(dspec:location))

(setf (get ',name 'saved-value)

(make-computed-saved-value :name ',name

:function ,function))

',name)))

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)

(funcall

(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"

:definedp

#'(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.

:object-dspec

#'(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:

(dspec:define-form-parser

(def-computed-saved-value

(: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