This example is based on that in Complete example of a top-level dspec class.
object has a function to compute the value the first time:
(defstruct (computed-saved-value (:include 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
Define a function to compute a
(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)
Define a macro to access a
(defmacro computed-saved-value (name)
Define a dspec class for
(dspec:define-dspec-class def-computed-saved-value def-saved-value
"Defined computed saved values"
;; Find any object that def-computed-saved-value recorded
(computed-saved-value-p (find-saved-value name)))
;; The :undefiner is inherited from the superspace.
;; 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:
Note: this form parser for
is not strictly necessary, because the implicit form parser will recognize definitions beginning with "def".