anchor.diff:               (setf (gethash ,(if store-key-p store-key key) ,hash-table)
                      (progn ,@body)))))))
   
  +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  +;;;
  +;;; Vector Memoization
  +
  +(defconstant +empty+ '+empty+)
  +
   (defmacro with-vector-memoization
  -    ((var &key (type t)) &body body)
  -  "Memoize the value of BODY for VAR being a relatively small integer and
  -   BODY returning a single value of type TYPE."
  -  (check-type var symbol)
  -  (with-gensyms (pool goal-var)
  -    `(let ((,pool
  -             (load-time-value
  -              (make-array 3 :fill-pointer 0
  -                            :element-type ',type
  -                            :adjustable t)))
  -           (,goal-var ,var))
  -       (declare (type array-index ,var ,goal-var)
  -                (type (vector ,type) ,pool))
  -       (loop for ,var from (fill-pointer ,pool) to ,goal-var do
  -         (vector-push-extend (progn ,@body) ,pool))
  -       (aref ,pool ,goal-var))))
  +    ((key &key (size 7) (growth 2.0)) &body body)
  +  "Memoize the value of BODY for KEY being a relatively small integer."
  +  (check-type size (integer 2 (#.array-total-size-limit)))
  +  (check-type growth (single-float (1.0) #.most-positive-single-float))
  +  (with-gensyms (value pool)
  +    (once-only (key)
  +      `(let* ((,pool
  +                (load-time-value
  +                 (make-array ,size :initial-element ,+empty+
  +                                   :adjustable t))))
  +         (loop until (array-in-bounds-p ,pool ,key) do
  +           (adjust-array ,pool (ceiling (* (length ,pool) ,growth))
  +                         :initial-element ,+empty+))
  +         (let ((,value (aref ,pool ,key)))
  +           (if (eq ,value ,+empty+)
  +               (setf (aref ,pool ,key) (progn ,@body))
  +               ,value))))))
   
  -(defmacro with-multiple-value-vector-memoization ((var) &body body)
  -  "Memoize the multiple values of BODY for VAR being a relatively small
  -   integer and BODY returning a single value of type TYPE."
  +(defmacro with-multiple-value-vector-memoization
  +    ((key &key (size 7) (growth 2.0)) &body body)
  +  "Memoize the values of BODY for VAR being a relatively small integer."
     `(values-list
  -    (with-vector-memoization (,var :type list)
  +    (with-vector-memoization (,key :size ,size :growth ,growth)
         (multiple-value-list (progn ,@body)))))
  -
  -(defmacro define-symbol-pool (name prefix)
  -  (check-type prefix string)
  -  (check-type name symbol)
  -  `(progn
  -     (defun ,name (n)
  -       (with-vector-memoization (n :type symbol)
  -         (intern (format nil "~A~D" ,prefix n))))
  -     (defun ,(symbolicate name "-LIST") (length)
  -       (with-vector-memoization (length :type list)
  -         (loop for n from (1- length) downto 0
  -               collect (,name n))))))
  -
  
positive.code: ;;; Marco Heisig's Memoization Macros
  ;;;
  ;;; There are numerous libraries for memoization, but most of them succumb
  ;;; the temptation to provide a wrapper for DEFUN as primary API. This
  ;;; fails to address several important use-cases
  ;;;
  ;;; - Memoization within CLOS, e.g. in :around methods
  
negative.code: ;;; - Explicit specification of the memoization test
  ;;;
  ;;; To address these problems, this library uses lexical memoization, i.e.
  ;;; WITH-something macros that memoize the result of evaluating their body.
  ;;; Furthermore, there are different memoization macros for more or less
  ;;; fine-grained control over the memoization strategy.
  ;;;
  ;;; Thread safety is deliberately neglected.  Unconditional thread safety
  ;;; is relatively expensive (but please, run your own benchmarks) and other
  ;;; solutions are necessarily application specific.  One could even state
  ;;; that thread-safety is an ill-defined term, because in an application
  ;;; where only one thread calls a particular memoizing function, this
  ;;; library IS thread safe.
  
  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;;;
  ;;; Hash Table Memoization
  
  (defmacro with-memoization
      ((key &key (test nil test-p) (store-key nil store-key-p)) &body body)
    "Memoize the value of BODY.  If KEY has the same value (with respect to
  TEST) as some previously computed key, then BODY is not evaluated and the
  values of the previous computation are returned.
  
  Note: TEST is evaluated at load time in a null lexical environment and must
  be a valid hash table test designator.
  
  If the optional form STORE-KEY is supplied, it is evaluated after any
  evaluation of BODY and its value is used instead of KEY for storing the
  results.  This way, KEY can be an object with dynamic extent (to avoid
  consing) and STORE-KEY can create a copy with indefinite extent when
  necessary."
    (once-only (key)
      `(with-hash-table-memoization
           (,key ,@(when store-key-p `(:store-key ,store-key)))
  