memoize-form

A simpler need than memoizing the results of a function with arguments is that of memoizing the results of a form. The tricky thing here is to do it just inline in the code, without using a global variable or such.

;; (MEMOIZED form) memoizes the result of form from its first evaluation.
;; Use like this:
;;    (defun secret-password (...) ....... (memoized (random 1000)) ......)

(eval-when (compile load eval) (when (eval '(flet ((ltv () (load-time-value (cons nil nil)))) (eq (ltv) (ltv)))) (pushnew :eval-uses-compiler *features*)))

(defmacro memoized (form) `(LET ((MEMORY (IF #-eval-uses-compiler (EVAL-WHEN (EVAL) T) #+eval-uses-compiler NIL ',(cons nil nil) ;; Careful: Different expansions of MEMOIZED forms must yield ;; LOAD-TIME-VALUE forms that are not EQ, otherwise compile-file ;; will coalesce these LOAD-TIME-VALUE forms. Therefore here we ;; explicitly cons up the list and don't use backquote. ,(list 'LOAD-TIME-VALUE '(CONS NIL NIL))))) (UNLESS (CAR MEMORY) (SETF (CDR MEMORY) ,form) (SETF (CAR MEMORY) T)) (CDR MEMORY)))


This page is linked from: memoize  

CLiki pages can be edited by anyone at any time. Imagine a fearsomely comprehensive disclaimer of liability. Now fear, comprehensively