emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Is this a bug in while-let or do I missunderstand it?


From: Joost Kremers
Subject: Re: Is this a bug in while-let or do I missunderstand it?
Date: Mon, 11 Nov 2024 23:41:50 +0100

On Sun, Nov 10 2024, Eli Zaretskii wrote:
> Anyway, to get this long discussion back on track: is there a need to
> clarify something in the documentation of while-let? if so, what?

Patch attached. Hope it's not too long, while still covering the gist of
what was discussed in this thread.

HTH

-- 
Joost Kremers
Life has its moments

>From fb3fd3bef67de821c469c0edb5b1cd6680736565 Mon Sep 17 00:00:00 2001
From: Joost Kremers <joostkremers@fastmail.com>
Date: Mon, 11 Nov 2024 23:38:49 +0100
Subject: [PATCH] Improve documentation for `while-let'.

* doc/lispref/control.texi: Improve documentation for `while-let`.
---
 doc/lispref/control.texi | 51 +++++++++++++++++++++++++++++++++-------
 1 file changed, 43 insertions(+), 8 deletions(-)

diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 80ed2ce899b..efc57fe7323 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -321,33 +321,68 @@ Conditionals
 There's a number of variations on this theme, and they're briefly
 described below.
 
-@defmac if-let* varlist then-form else-forms...
-Evaluate each binding in @var{varlist} in turn, like in @code{let*}
+@defmac if-let* spec then-form else-forms...
+Evaluate each binding in @var{spec} in turn, like in @code{let*}
 (@pxref{Local Variables}), stopping if a binding value is @code{nil}.
 If all are non-@code{nil}, return the value of @var{then-form},
 otherwise the last form in @var{else-forms}.
 @end defmac
 
-@defmac when-let* varlist then-forms...
+@defmac when-let* spec then-forms...
 Like @code{if-let*}, but without @var{else-forms}.
 @end defmac
 
-@defmac and-let* varlist then-forms...
+@defmac and-let* spec then-forms...
 Like @code{when-let*}, but in addition, if there are no
 @var{then-forms} and all the bindings evaluate to non-@code{nil}, return
 the value of the last binding.
 @end defmac
 
-@defmac while-let spec then-forms...
-Like @code{when-let*}, but repeat until a binding in @var{spec} is
-@code{nil}.  The return value is always @code{nil}.
-@end defmac
+Each element of the @code{spec} argument in these macros has the form
+@code{(@var{symbol} @var{value-form})}: @var{value-form} is evaluated
+and @var{symbol} is locally bound to the result.  As a special case,
+@var{symbol} can be omitted if the result of @var{value-form} just needs
+to be tested and there's no need to bind it to a variable.
 
 Some Lisp programmers follow the convention that @code{and} and
 @code{and-let*} are for forms evaluated for return value, and
 @code{when} and @code{when-let*} are for forms evaluated for side-effect
 with returned values ignored.
 
+A similar macro exists to run a loop until one binding evaluates to
+@code{nil}:
+
+@defmac while-let spec then-forms...
+Evaluate each binding in @var{spec} in turn, stopping if a binding value
+is @code{nil}.  If all are non-@code{nil}, execute @var{then-forms},
+then repeat the loop.  The return value is always @code{nil}.
+
+@code{while-let} replaces a pattern in which a binding is established
+outside the @code{while}-loop, tested as part of the condition of
+@code{while} and subsequently changed inside the loop using the same
+expression that it was originally bound to:
+
+@example
+(let ((result (do-computation)))
+  (while result
+    (do-stuff-with result)
+    (setq result (do-computation))))
+@end example
+
+Using @code{while-let}, this can be written more succinctly as:
+
+@example
+(while-let ((result (do-computation)))
+  (do-stuff-with result))
+@end example
+
+One crucial difference here is the fact that in the first code example,
+@code{result} is scoped outside the @code{wile} loop, whereas in the
+second example, its scope is confined to the @code{while-let} loop.  As
+a result, changing the value of @code{result} inside the loop has no
+effect on the subsequent iteration.
+@end defmac
+
 @node Combining Conditions
 @section Constructs for Combining Conditions
 @cindex combining conditions
-- 
2.47.0


reply via email to

[Prev in Thread] Current Thread [Next in Thread]