1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-06 06:20:55 -08:00

Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs

This commit is contained in:
Eli Zaretskii 2025-11-05 18:57:27 +02:00
commit 9e905357bb
4 changed files with 66 additions and 6 deletions

View file

@ -317,8 +317,8 @@ following way instead:
(do-something result2)) (do-something result2))
@end example @end example
There's a number of variations on this theme, and they're briefly There's a number of variations on this theme, and they're described
described below. below.
@defmac if-let* varlist then-form else-forms... @defmac if-let* varlist then-form else-forms...
Evaluate each binding in @var{varlist}, stopping if a binding value is Evaluate each binding in @var{varlist}, stopping if a binding value is
@ -376,6 +376,22 @@ Some Lisp programmers follow the convention that @code{and} and
@code{when} and @code{when-let*} are for forms evaluated for side-effect @code{when} and @code{when-let*} are for forms evaluated for side-effect
with returned values ignored. with returned values ignored.
There is no @code{cond-let*} macro because extending the structure
shared by @code{if-let*}, @code{when-let*} and @code{and-let*} to the
case of @code{cond} is not simple.@footnote{The problem is that there
are multiple ways to do it that are all useful but not compatible. In
addition, the resulting macro is complicated, and so tricky to learn how
to read and write.} However, you can use the @code{cond*} macro's
@code{bind-and*} clauses (@pxref{cond* Macro}) to achieve something
similar:
@example
(cond* ((bind-and* (result1 (do-computation))
(result2 (do-more result1)))
(do-something result2))
...)
@end example
A similar macro exists to run a loop until one binding evaluates to A similar macro exists to run a loop until one binding evaluates to
@code{nil}: @code{nil}:
@ -1503,6 +1519,14 @@ the bindings list in @code{let*}, @pxref{Local Variables}) for the body
of the clause, and all subsequent clauses. As a condition, it counts as of the clause, and all subsequent clauses. As a condition, it counts as
true if the first binding's value is non-@code{nil}. true if the first binding's value is non-@code{nil}.
@findex bind-and*
@code{(bind-and* @var{bindings}@dots{})} means to bind @var{bindings}
(like the bindings list in @code{if-let*}, @pxref{Conditionals}) for
only the body of the clause. As a condition, it counts as true if none
of the bindings evaluate to @code{nil}. In addition, if any binding
evaluates to @code{nil}, the expressions for the values of subsequent
bindings are not evaluated.
@findex match* @findex match*
@findex pcase* @findex pcase*
@code{(match* @var{pattern} @var{datum})} means to match @var{datum} @code{(match* @var{pattern} @var{datum})} means to match @var{datum}

View file

@ -3049,6 +3049,16 @@ Other functions that use 'aset' to modify string data, such as
'subst-char-in-string' with a non-nil INPLACE argument, will signal an 'subst-char-in-string' with a non-nil INPLACE argument, will signal an
error if called with arguments that would violate these rules. error if called with arguments that would violate these rules.
+++
** More program constants are combined by the compiler.
The compiler now unifies more constants that are 'equal' for better code
generation. This does not affect correct programs but may expose some
coding mistakes. For example,
(eq (cdr '(1 2 3)) '(2 3)))
may return either nil or t.
** Nested backquotes are not supported any more in Pcase patterns. ** Nested backquotes are not supported any more in Pcase patterns.
--- ---

View file

@ -3870,8 +3870,7 @@ assignment (i.e. `setq')."
(byte-compile-dynamic-variable-op 'byte-varset var)))) (byte-compile-dynamic-variable-op 'byte-varset var))))
(defmacro byte-compile-get-constant (const) (defmacro byte-compile-get-constant (const)
`(or (assoc ,const byte-compile-constants `(or (assoc ,const byte-compile-constants #'equal-including-properties)
(if (stringp ,const) #'equal-including-properties #'eql))
(car (setq byte-compile-constants (car (setq byte-compile-constants
(cons (list ,const) byte-compile-constants))))) (cons (list ,const) byte-compile-constants)))))

View file

@ -2756,7 +2756,34 @@ Affects only hooks run in the current buffer."
(let ((delay-mode-hooks t)) (let ((delay-mode-hooks t))
,@body))) ,@body)))
;;; `when-let' and friends. ;;; `if-let*' and friends.
;;;
;;; We considered adding a `cond-let*' in late 2025:
;;; <https://lists.gnu.org/archive/html/emacs-devel/2025-09/msg00058.html>.
;;; We decided to add the `bind-and*' clause type to `cond*' instead.
;;; At first it seems simple to extend `if-let*'/`when-let*'/`and-let*'
;;; to `cond', but the extension is not unambiguous: there are multiple
;;; useful, incompatible ways to do it.
;;; In particular, it quickly becomes clear that one wants clauses that
;;; only establish bindings for proceeding clauses, instead of exiting
;;; the `cond-let*'. But then
;;; - Should these bindings be just like in `let*', or like in
;;; `if-let*'? In other words, should it be that if a binding
;;; evaluates to nil we skip the remaining bindings (bind them all to
;;; nil)? Both ways of doing it seem useful.
;;; - The parentheses quickly pile up. How can we avoid the programmer
;;; having to count parentheses? Some propose using square brackets
;;; (i.e., vectors) for the binding-only clauses, but Emacs Lisp is a
;;; traditional Lisp which uses exclusively parentheses for control
;;; constructs. Therefore, introducing square brackets here would be
;;; jarring to read. Another option would be to use symbols at the
;;; beginning of clauses, like `cond*' does.
;;; Whichever way one goes, the resulting macro ends up complicated,
;;; with a substantial learning burden. Adding `bind-and*' clauses to
;;; `cond*' gives us the desired functionality, and does not make
;;; `cond*' much more complicated. In other words, `cond*' is already
;;; complicated, and one complicated `cond'-extending macro is better
;;; than two. --spwhitton
(defun internal--build-binding (binding prev-var) (defun internal--build-binding (binding prev-var)
"Check and build a single BINDING with PREV-VAR." "Check and build a single BINDING with PREV-VAR."
@ -2803,7 +2830,7 @@ binding of SYMBOL is checked for nil, only.
An older form for entries of VARLIST is also supported, where SYMBOL is An older form for entries of VARLIST is also supported, where SYMBOL is
omitted, i.e. (VALUEFORM). This means the same as (_ VALUEFORM). omitted, i.e. (VALUEFORM). This means the same as (_ VALUEFORM).
This form is not recommended because many programmers find it This form is not recommended because many Lisp programmers find it
significantly less readable. A future release of Emacs may introduce a significantly less readable. A future release of Emacs may introduce a
byte-compiler warning for uses of (VALUEFORM) in VARLIST." byte-compiler warning for uses of (VALUEFORM) in VARLIST."
(declare (indent 2) (declare (indent 2)