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: Sun, 10 Nov 2024 11:40:39 +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?

Speaking for me personally, I do think the documentation esp. of
`while-let` is too terse. I think two improvements could be made. The first
would be to explicitly mention the pattern that `while-let` replaces, i.e.,

```
(let ((result (do-computation)))
  (while result
    (do-stuff-with result)
    (setq result (do-computation))))
```

The manual at (info "(elisp) Conditionals") discusses the pattern that
`when-let` replaces; `if-let` can be deduced from that, as it's similar.
But `while-let` is different because of the additional `setq` in the
pattern it replaces.

Second, I think it would help if the fact that the bindings are
reestablished upon every iteration were mentioned explicitly. This seems to
have confused Arthur, and I asked myself the same question when I first
encountered `while-let`.

I'd offer the following as a first attempt:

```
@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}.

@code{while-let} replaces a common pattern in which a binding is
established outside the @{while}-loop, tested as part of the condition of
@{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

The binding of @code{result} is reestablished at every iteration, therefore
setting the value of @code{result} inside the loop has no effect. In order
to end the loop, @code{(do-computation)} should eventually return
@code{nil}.

This example uses a single binding for clarity, but obviously
@code{while-let} can establish multiple bindings. The loop runs as long as
all bindings are non-@code{nil}.
@end defmac
```

Am I mistaken or is `while-let` a bit like a do..until loop that some
languages offer?


-- 
Joost Kremers
Life has its moments



reply via email to

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