(defun gen-memo (fn key test)
(let ((table (make-hash-table :test test)))
(values table
(lambda (&rest args)
(let ((k (funcall key args)))
(multiple-value-bind (val found-p) (gethash k table)
(if found-p
val
(setf (gethash k table)
(apply fn args)))))))))Source Context