From da47fa2f23bde6cc96f90f56ccf383128affb748 Mon Sep 17 00:00:00 2001 From: Sean Whitton Date: Tue, 7 Oct 2025 17:31:34 +0100 Subject: [PATCH] if-let*/when-let*/and-let*: Don't recommend (VALUEFORM) form * doc/lispref/control.texi (Conditionals): * lisp/subr.el (if-let*): Document '(_ VALUEFORM)' instead of '(VALUEFORM)'. --- doc/lispref/control.texi | 21 ++++++++++----------- lisp/subr.el | 21 +++++++++++++++------ 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 689e7324d43..8f1f144e765 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -317,7 +317,7 @@ following way instead: (do-something result2)) @end example -There's a number of variations on this theme, and they're briefly +There are a number of variations on this theme, and they're briefly described below. @defmac if-let* varlist then-form else-forms... @@ -328,10 +328,9 @@ Evaluate each binding in @var{varlist}, stopping if a binding value is Each element of @code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}: @var{value-form} is evaluated and @var{symbol} is locally bound to the result. Bindings are sequential, as in @code{let*} -(@pxref{Local Variables}). As a special case, @var{symbol} can be -omitted if only the test result of @var{value-form} is of interest: -@var{value-form} is evaluated and checked for @code{nil}, but its value -is not bound. +(@pxref{Local Variables}). If only the test result of @var{value-form} +is of interest, use @code{_} for @var{symbol}. Then @var{value-form} is +evaluated and checked for @code{nil}, but its value is not bound. @end defmac @defmac when-let* varlist then-forms... @@ -343,8 +342,8 @@ form in @var{then-forms}. @code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, in which @var{value-form} is evaluated and @var{symbol} is locally bound to the result. Bindings are sequential, as in @code{let*} (@pxref{Local -Variables}). As a special case, @var{symbol} can be omitted if only the -test result of @var{value-form} is of interest: @var{value-form} is +Variables}). If only the test result of @var{value-form} +is of interest, use @code{_} for @var{symbol}. Then @var{value-form} is evaluated and checked for @code{nil}, but its value is not bound. @end defmac @@ -358,8 +357,8 @@ the value of the last binding. @code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, in which @var{value-form} is evaluated and @var{symbol} is locally bound to the result. Bindings are sequential, as in @code{let*} (@pxref{Local -Variables}). As a special case, @var{symbol} can be omitted if only the -test result of @var{value-form} is of interest: @var{value-form} is +Variables}). If only the test result of @var{value-form} is of +interest, use @code{_} for @var{symbol}. Then @var{value-form} is evaluated and checked for @code{nil}, but its value is not bound. @end defmac @@ -382,8 +381,8 @@ established anew. @code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, in which @var{value-form} is evaluated and @var{symbol} is locally bound to the result. Bindings are sequential, as in @code{let*} (@pxref{Local -Variables}). As a special case, @var{symbol} can be omitted if only the -test result of @var{value-form} is of interest: @var{value-form} is +Variables}). If only the test result of @var{value-form} is of +interest, use @code{_} for @var{symbol}. Then @var{value-form} is evaluated and checked for @code{nil}, but its value is not bound. The return value of @code{while-let} is always @code{nil}. diff --git a/lisp/subr.el b/lisp/subr.el index 50ebc598e80..7bd436d898a 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2632,6 +2632,9 @@ Affects only hooks run in the current buffer." binding)) bindings))) +;; FIXME: Once Emacs 29 is ancient history we can consider a +;; byte-compiler warning. This is because Emacs 29 and older will warn +;; about unused variables with (_ VALUEFORM). (defmacro if-let* (varlist then &rest else) "Bind variables according to VARLIST and evaluate THEN or ELSE. Evaluate each binding in turn, as in `let*', stopping if a @@ -2639,12 +2642,18 @@ binding value is nil. If all are non-nil return the value of THEN, otherwise the value of the last form in ELSE, or nil if there are none. -Each element of VARLIST is a list (SYMBOL VALUEFORM) that binds -SYMBOL to the value of VALUEFORM. An element can additionally be -of the form (VALUEFORM), which is evaluated and checked for nil; -i.e. SYMBOL can be omitted if only the test result is of -interest. It can also be of the form SYMBOL, then the binding of -SYMBOL is checked for nil." +Each element of VARLIST is a list (SYMBOL VALUEFORM) that binds SYMBOL +to the value of VALUEFORM. If only the test result is of interest, use +`_' as SYMBOL, i.e. (_ VALUEFORM), in which case VALUEFORM is evaluated +and checked for nil but the result is not bound. +An element of VARLIST can also be of the form SYMBOL, in which case the +binding of SYMBOL is checked for nil, only. + +An older form for entries of VARLIST is also supported, where SYMBOL is +omitted, i.e. (VALUEFORM). This means the same as (_ VALUEFORM). +This form is not recommended because many programmers find it +significantly less readable. A future release of Emacs may introduce a +byte-compiler warning for uses of (VALUEFORM) in VARLIST." (declare (indent 2) (debug ((&rest [&or symbolp (symbolp form) (form)]) body)))