From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Joost Kremers Newsgroups: gmane.emacs.devel Subject: Re: Is this a bug in while-let or do I missunderstand it? Date: Mon, 11 Nov 2024 23:41:50 +0100 Message-ID: <865xot2y1d.fsf@fastmail.fm> References: <86ldxrliau.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11687"; mail-complaints-to="usenet@ciao.gmane.io" Cc: arthur miller , ams@gnu.org, yuri.v.khan@gmail.com, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Mon Nov 11 23:43:09 2024 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1tAd7k-0002rf-0G for ged-emacs-devel@m.gmane-mx.org; Mon, 11 Nov 2024 23:43:09 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tAd6o-000573-08; Mon, 11 Nov 2024 17:42:10 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tAd6m-00056b-7I for emacs-devel@gnu.org; Mon, 11 Nov 2024 17:42:08 -0500 Original-Received: from fhigh-b6-smtp.messagingengine.com ([202.12.124.157]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tAd6h-00081y-QE; Mon, 11 Nov 2024 17:42:07 -0500 Original-Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id 3B4852540118; Mon, 11 Nov 2024 17:41:58 -0500 (EST) Original-Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-02.internal (MEProxy); Mon, 11 Nov 2024 17:41:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.fm; h= cc:cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1731364918; x=1731451318; bh=fOy71KuGiU Xd20I89WJRMZdVPxBCIG1r4SJZv+p58Z0=; b=DOWfLKbcLpJJ3Ndi22GHpcQ1wR Qw0q/AwiMArv7tXgMZc2Fmua5thjVut06AUBwinlngHr2G1htnLX1OxdPeBhgnyY RKHVxest8/KZDlhfsRAcNe4AMmlUI7OVDSQ/VI+37/dbvSkIHB9B4KYsTuSxtNRl GY/fy5kKysKKqFaZ+SVoKJmHWQ2CH859rkJrUTk1hDw2M08X7JHbkWnM+SpPr9Ph Q1g/UwnkFtzclmnqQc+TogJDOsr2/9j4c1tm+l2JOW9/sV9BetXxWA8XlM6RUK4U AIY9ygnUoOj0wRybmX2HlPGJC90EKIGcIxTYtLLOtZ7qbPNe8nDdsYmy6YWw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1731364918; x=1731451318; bh=fOy71KuGiUXd20I89WJRMZdVPxBCIG1r4SJ Zv+p58Z0=; b=OAYQNrfTqefwn0fbv2utIvcnI/KVQjw727x7qYh6OOtdWeqB4X1 l+wfAVBnQcsPg6c3v3EvXGZtqzcqoxXJVIZuWjktJQn3vNhhDQsrSnj9WYldIbuU 0VEIuiB6z0GlDCS0krgV9ay0aJd/S2ZysrVnp3AsRcRcQfVx2BJY75KmApAnNkK3 ahYaRn2JNollDGfuNyNycSt5D2SzmvGjEmUOaSM1ApvkIAYawwT7lgsNqa8bNnUj Coogz3cnKi8+5zbg/sFIffFh3oAt5WefGuGfU9PR6F+QYIbmmazHNzHHj06tImxw qjWKJHVhON4XLW1RZWLLxkkwEyR4vvnPgZw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudefgddtvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdpuffr tefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnth hsucdlqddutddtmdenucfjughrpefhvfevufgjfhffkfggtgesmhdtreertddttdenucfh rhhomheplfhoohhsthcumfhrvghmvghrshcuoehjohhoshhtkhhrvghmvghrshesfhgrsh htmhgrihhlrdhfmheqnecuggftrfgrthhtvghrnhepvdeuudfghfdtvedttdelvdeludel heehfeevfffgvdehjedvieeiveekjeeikefgnecuvehluhhsthgvrhfuihiivgeptdenuc frrghrrghmpehmrghilhhfrhhomhepjhhoohhsthhkrhgvmhgvrhhssehfrghsthhmrghi lhdrfhhmpdhnsggprhgtphhtthhopeehpdhmohguvgepshhmthhpohhuthdprhgtphhtth hopegvmhgrtghsqdguvghvvghlsehgnhhurdhorhhgpdhrtghpthhtohephihurhhirdhv rdhkhhgrnhesghhmrghilhdrtghomhdprhgtphhtthhopegrmhhssehgnhhurdhorhhgpd hrtghpthhtoheprghrthhhuhhrrdhmihhllhgvrheslhhivhgvrdgtohhmpdhrtghpthht ohepvghlihiisehgnh X-ME-Proxy: Feedback-ID: ie15541ac:Fastmail Original-Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 11 Nov 2024 17:41:55 -0500 (EST) In-Reply-To: <86ldxrliau.fsf@gnu.org> (Eli Zaretskii's message of "Sun, 10 Nov 2024 08:22:17 +0200") Received-SPF: pass client-ip=202.12.124.157; envelope-from=joostkremers@fastmail.fm; helo=fhigh-b6-smtp.messagingengine.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:325413 Archived-At: --=-=-= Content-Type: text/plain 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 --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Improve-documentation-for-while-let.patch >From fb3fd3bef67de821c469c0edb5b1cd6680736565 Mon Sep 17 00:00:00 2001 From: Joost Kremers 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 --=-=-=--