summaryrefslogtreecommitdiff
path: root/devdocs/elisp/deferred-eval.html
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
committerCraig Jennings <c@cjennings.net>2024-04-07 13:41:34 -0500
commit754bbf7a25a8dda49b5d08ef0d0443bbf5af0e36 (patch)
treef1190704f78f04a2b0b4c977d20fe96a828377f1 /devdocs/elisp/deferred-eval.html
new repository
Diffstat (limited to 'devdocs/elisp/deferred-eval.html')
-rw-r--r--devdocs/elisp/deferred-eval.html55
1 files changed, 55 insertions, 0 deletions
diff --git a/devdocs/elisp/deferred-eval.html b/devdocs/elisp/deferred-eval.html
new file mode 100644
index 00000000..18d7dc2f
--- /dev/null
+++ b/devdocs/elisp/deferred-eval.html
@@ -0,0 +1,55 @@
+ <h3 class="section">Deferred and Lazy Evaluation</h3> <p>Sometimes it is useful to delay the evaluation of an expression, for example if you want to avoid performing a time-consuming calculation if it turns out that the result is not needed in the future of the program. The <samp>thunk</samp> library provides the following functions and macros to support such <em>deferred evaluation</em>: </p> <dl> <dt id="thunk-delay">Macro: <strong>thunk-delay</strong> <em>forms…</em>
+</dt> <dd><p>Return a <em>thunk</em> for evaluating the <var>forms</var>. A thunk is a closure (see <a href="closures">Closures</a>) that inherits the lexical environment of the <code>thunk-delay</code> call. Using this macro requires <code>lexical-binding</code>. </p></dd>
+</dl> <dl> <dt id="thunk-force">Function: <strong>thunk-force</strong> <em>thunk</em>
+</dt> <dd><p>Force <var>thunk</var> to perform the evaluation of the forms specified in the <code>thunk-delay</code> that created the thunk. The result of the evaluation of the last form is returned. The <var>thunk</var> also “remembers” that it has been forced: Any further calls of <code>thunk-force</code> with the same <var>thunk</var> will just return the same result without evaluating the forms again. </p></dd>
+</dl> <dl> <dt id="thunk-let">Macro: <strong>thunk-let</strong> <em>(bindings…) forms…</em>
+</dt> <dd><p>This macro is analogous to <code>let</code> but creates “lazy” variable bindings. Any binding has the form <code>(<var>symbol</var> <var><span class="nolinebreak">value-form</span></var>)</code>. Unlike <code>let</code>, the evaluation of any <var>value-form</var> is deferred until the binding of the according <var>symbol</var> is used for the first time when evaluating the <var>forms</var>. Any <var>value-form</var> is evaluated at most once. Using this macro requires <code>lexical-binding</code>. </p></dd>
+</dl> <p>Example: </p> <div class="example"> <pre class="example">(defun f (number)
+ (thunk-let ((derived-number
+ (progn (message "Calculating 1 plus 2 times %d" number)
+ (1+ (* 2 number)))))
+ (if (&gt; number 10)
+ derived-number
+ number)))
+</pre>
+
+<pre class="example">(f 5)
+⇒ 5
+</pre>
+
+<pre class="example">(f 12)
+-| Calculating 1 plus 2 times 12
+⇒ 25
+</pre>
+
+</div> <p>Because of the special nature of lazily bound variables, it is an error to set them (e.g. with <code>setq</code>). </p> <dl> <dt id="thunk-let*">Macro: <strong>thunk-let*</strong> <em>(bindings…) forms…</em>
+</dt> <dd><p>This is like <code>thunk-let</code> but any expression in <var>bindings</var> is allowed to refer to preceding bindings in this <code>thunk-let*</code> form. Using this macro requires <code>lexical-binding</code>. </p></dd>
+</dl> <div class="example"> <pre class="example">(thunk-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
+
+</pre>
+</div> <p><code>thunk-let</code> and <code>thunk-let*</code> use thunks implicitly: their expansion creates helper symbols and binds them to thunks wrapping the binding expressions. All references to the original variables in the body <var>forms</var> are then replaced by an expression that calls <code>thunk-force</code> with the according helper variable as the argument. So, any code using <code>thunk-let</code> or <code>thunk-let*</code> could be rewritten to use thunks, but in many cases using these macros results in nicer code than using thunks explicitly. </p><div class="_attribution">
+ <p class="_attribution-p">
+ Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
+ <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Deferred-Eval.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Deferred-Eval.html</a>
+ </p>
+</div>