Deferred and lazy evaluation Sometimes it is useful to delay the evaluation of an expression, for example if you want to avoid to perform a time-consuming calculation in the case that it turns out that the result is not needed in the future of the program. -- Macro: thunk-delay FORMS... Return a thunk for evaluating the FORMS. A thunk is a closure that evaluates the FORMS in the lexical environment present when `thunk-delay' has been called. -- Function: thunk-force THUNK Force a thunk to perform the evaluation of the FORMS specified to the `thunk-delay' that created the thunk. The result of the evaluation of the last form is returned. The THUNK also "remembers" that it has been forced: Any further calls of `thunk-force' on the same THUNK will just return the same result without evaluating the FORMS again. -- Macro: lazy-let (bindings...) forms... This macro is analogue to `let' but creates "lazy" variable bindings. Any binding has the form (SYMBOL VALUE-FORM). Unlike `let', the evaluation of any VALUE-FORM is deferred until the binding of the according SYMBOL is used for the first time when evaluating the FORMS. Any VALUE-FORM is evaluated maximally once. Example: (defun f (number) (lazy-let ((derived-number (progn (message "Calculating 1 plus 2 times %d" number) (1+ (* 2 number))))) (if (> number 10) derived-number number))) (f 5) ==> 5 (f 12) |--> "Calculating 1 plus 2 times 12" 25 Because of the special nature of lazily bound variables, it is an error to set them (e.g. with `setq'). -- Macro: lazy-let* (bindings...) forms... This is like `lazy-let' but any expression in BINDINGS is allowed to refer to preceding bindings in this `lazy-let*' form. Example: (lazy-let* ((x (prog2 (message "Calculating x...") (+ 1 1) (message "Finished calculating x"))) (y (prog2 (message "Calculating y...") (+ x 1) (message "Finished calculating y"))) (z (prog2 (message "Calculating z...") (+ y 1) (message "Finished calculating z"))) (a (prog2 (message "Calculating a...") (+ z 1) (message "Finished calculating a")))) (* z x)) |--> Calculating z... |--> Calculating y... |--> Calculating x... |--> Finished calculating x |--> Finished calculating y |--> Finished calculating z ==> 8 `lazy-let' and `lazy-let*' use thunks implicitly: their expansion creates helper symbols and binds them to thunks wrapping the binding expressions. All rerences to the original variables in the FORMS are then replaced by an expression that calls `thunk-force' on the according helper variable. So, any code using `lazy-let' or `lazy-let*' could be rewritten to use thunks, but in many cases using these macros results in nicer code than using thunks explicitly.