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