From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Marco Antoniotti Newsgroups: gmane.emacs.bugs Subject: bug#70597: Problem in pcase-let? Date: Sun, 5 May 2024 10:49:33 +0200 Message-ID: References: <662d23bf.050a0220.a4e2f.3f45@mx.google.com> <865xvwmus2.fsf@gnu.org> <861q6hhks0.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000d87b2c0617b10803" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="40255"; mail-complaints-to="usenet@ciao.gmane.io" Cc: brubar.cs@gmail.com, Eli Zaretskii , 70597-done@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sun May 05 10:50:56 2024 Return-path: Envelope-to: geb-bug-gnu-emacs@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 1s3XaB-000AFe-4q for geb-bug-gnu-emacs@m.gmane-mx.org; Sun, 05 May 2024 10:50:55 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1s3XZz-0004iU-R8; Sun, 05 May 2024 04:50:43 -0400 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 1s3XZv-0004hm-RU for bug-gnu-emacs@gnu.org; Sun, 05 May 2024 04:50:40 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1s3XZv-0008Iu-Ak for bug-gnu-emacs@gnu.org; Sun, 05 May 2024 04:50:39 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1s3XaI-0002gl-EV for bug-gnu-emacs@gnu.org; Sun, 05 May 2024 04:51:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Marco Antoniotti Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 05 May 2024 08:51:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 70597 X-GNU-PR-Package: emacs Original-Received: via spool by 70597-done@debbugs.gnu.org id=D70597.171489902010317 (code D ref 70597); Sun, 05 May 2024 08:51:02 +0000 Original-Received: (at 70597-done) by debbugs.gnu.org; 5 May 2024 08:50:20 +0000 Original-Received: from localhost ([127.0.0.1]:58502 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s3XZb-0002gK-OR for submit@debbugs.gnu.org; Sun, 05 May 2024 04:50:20 -0400 Original-Received: from mail-yb1-xb2f.google.com ([2607:f8b0:4864:20::b2f]:48403) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1s3XZX-0002g7-IO for 70597-done@debbugs.gnu.org; Sun, 05 May 2024 04:50:19 -0400 Original-Received: by mail-yb1-xb2f.google.com with SMTP id 3f1490d57ef6-d9b9adaf291so828618276.1 for <70597-done@debbugs.gnu.org>; Sun, 05 May 2024 01:49:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1714898986; x=1715503786; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=wYcLseDCkElvt42BUptEsZKXekSrj/OT5QM+fgW1xbE=; b=A/IgZ1j/fOA95UF7LHwKb8ZyP0HoRzo9piU49dgAURdgo3uxTi1djDG/Mr8IwsShuk 9amc9bodSxqaTv4zh9jhoshY34acgVWDVJguGQeOBO8lOyEhQnCmZq0NGi5QUl9RB4Ib zUW2y/ynLPp/yrUKPn03XAZyGKoE+iQXmtJIgtuYelOGMr+0SEVyxGO9FiThAwxszzBa 0NQ1173qDtWK0JRroMgwJHkkpg7d61VG1yKvselNbiXWyCMjRibMyM92jiUS+h9txD1W Bgheam5TrxSYXgNMFmb/5gYYJBABNPvYvIDq+GkLXh6hNFiTn6pHWbSN/okBKucgaJhC HFOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1714898986; x=1715503786; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=wYcLseDCkElvt42BUptEsZKXekSrj/OT5QM+fgW1xbE=; b=cCM4s4GVuISP9p654Ox0vXr+6vJO/BGlKyk/yL0ajraYp14r3Z1hIxCczC3aPI3Oft 53oD0X4UQOb+/A8hDXV+5rAvJGnPpTDg21c7liJFCckf+qCh1UNBAwEyymZmE+ZzBSiV ns49ec0GADw/AcrHIj2X7wWT4DfhrzVThp2vgLW+z61ceGtjwxgOQHzXH4QlChnkUd7A sKhrxQdbOwY8alUFcfTYCnb+ynRDx3KUJBmkxoN5T8+7Zd06Zibllt+ybIU59q3BXSQ/ e1il29+eSgJKoWHUSLVY52RuiI4AQsAHlxkPRUmcqsYcKtMT/+76e9S/CewvZJbxw6w/ YHpA== X-Forwarded-Encrypted: i=1; AJvYcCU9YP9r+U9rLlg20Quas67wjezCSVZ0WIh9Qa29i5kVzflj2Y+700PD+PsZe0fyBkefA7LGGIlwqF7losivM5KewvsZ242QyywOMw== X-Gm-Message-State: AOJu0YzaIGJzMWfO61gcibT7MElhovfBPAzm0qVmhwco0cupiBERmBGF Qnfw33f+g8TVkkvjEcUyBI/mvNlEacdDFcIEykzQxxoaQ5YwbRy/Mya9o1obDFBl0wHlfulA4Y9 zd9W8kob0QcEMTYBbJAEAwX/9grk= X-Google-Smtp-Source: AGHT+IG41be1Ru1vbHowyJI2I+PNURMZX4eZOvr6dZ6a3HEuCwLSEfVqnrp5FaZPSINlISrbYLJDodFAHsjNNUzIRaU= X-Received: by 2002:a25:9383:0:b0:de5:5266:bbbc with SMTP id a3-20020a259383000000b00de55266bbbcmr6501603ybm.28.1714898985316; Sun, 05 May 2024 01:49:45 -0700 (PDT) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:284488 Archived-At: --000000000000d87b2c0617b10803 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Stefan, i usually just to C-h f. This is what you get from it, in 29.3. Like `let', but supports destructuring BINDINGS using `pcase' patterns. BODY should be a list of expressions, and BINDINGS should be a list of bindings of the form (PATTERN EXP). All EXPs are evaluated first, and then used to perform destructuring bindings by matching each EXP against its respective PATTERN. Then BODY is evaluated with those bindings in effect. Each EXP should match its respective PATTERN (i.e. be of structure compatible to PATTERN); a mismatch may signal an error or may go undetected, binding variables to arbitrary values, such as nil. Probably introduced at or before Emacs version 28.1. The Info doc you posted is definitively better. All the best MA On Sat, May 4, 2024 at 5:05=E2=80=AFPM Stefan Monnier wrote: > > sorry, but I do not think that the current doc string and/or the > > manual explains the situation. > > Which "current" are you referring to? The "current" manual (in > `master`) has a whole section on "Destructuring with pcase pattern" > (see below). > > Do you still see room for misunderstanding there? > If so, can you suggest how to change it to make it more clear? > > > Stefan > > > @node Destructuring with pcase Patterns > @subsection Destructuring with @code{pcase} Patterns > @cindex destructuring with pcase patterns > > Pcase patterns not only express a condition on the form of the objects > they can match, but they can also extract sub-fields of those objects. > For example we can extract 2 elements from a list that is the value of > the variable @code{my-list} with the following code: > > @example > (pcase my-list > (`(add ,x ,y) (message "Contains %S and %S" x y))) > @end example > > This will not only extract @code{x} and @code{y} but will additionally > test that @code{my-list} is a list containing exactly 3 elements and > whose first element is the symbol @code{add}. If any of those tests > fail, @code{pcase} will immediately return @code{nil} without calling > @code{message}. > > Extraction of multiple values stored in an object is known as > @dfn{destructuring}. Using @code{pcase} patterns allows you to > perform @dfn{destructuring binding}, which is similar to a local > binding (@pxref{Local Variables}), but gives values to multiple > elements of a variable by extracting those values from an object of > compatible structure. > > The macros described in this section use @code{pcase} patterns to > perform destructuring binding. The condition of the object to be of > compatible structure means that the object must match the pattern, > because only then the object's subfields can be extracted. For > example: > > @example > (pcase-let ((`(add ,x ,y) my-list)) > (message "Contains %S and %S" x y)) > @end example > > @noindent > does the same as the previous example, except that it directly tries > to extract @code{x} and @code{y} from @code{my-list} without first > verifying if @code{my-list} is a list which has the right number of > elements and has @code{add} as its first element. The precise > behavior when the object does not actually match the pattern is > undefined, although the body will not be silently skipped: either an > error is signaled or the body is run with some of the variables > potentially bound to arbitrary values like @code{nil}. > > The pcase patterns that are useful for destructuring bindings are > generally those described in @ref{Backquote Patterns}, since they > express a specification of the structure of objects that will match. > > For an alternative facility for destructuring binding, see > @ref{seq-let}. > > @defmac pcase-let bindings body@dots{} > Perform destructuring binding of variables according to > @var{bindings}, and then evaluate @var{body}. > > @var{bindings} is a list of bindings of the form @w{@code{(@var{pattern} > @var{exp})}}, where @var{exp} is an expression to evaluate and > @var{pattern} is a @code{pcase} pattern. > > All @var{exp}s are evaluated first, after which they are matched > against their respective @var{pattern}, introducing new variable > bindings that can then be used inside @var{body}. The variable > bindings are produced by destructuring binding of elements of > @var{pattern} to the values of the corresponding elements of the > evaluated @var{exp}. > > Here's a trivial example: > > @example > (pcase-let ((`(,major ,minor) > (split-string "image/png" "/"))) > minor) > @result{} "png" > @end example > @end defmac > > @defmac pcase-let* bindings body@dots{} > Perform destructuring binding of variables according to > @var{bindings}, and then evaluate @var{body}. > > @var{bindings} is a list of bindings of the form @code{(@var{pattern} > @var{exp})}, where @var{exp} is an expression to evaluate and > @var{pattern} is a @code{pcase} pattern. The variable bindings are > produced by destructuring binding of elements of @var{pattern} to the > values of the corresponding elements of the evaluated @var{exp}. > > Unlike @code{pcase-let}, but similarly to @code{let*}, each @var{exp} > is matched against its corresponding @var{pattern} before processing > the next element of @var{bindings}, so the variable bindings > introduced in each one of the @var{bindings} are available in the > @var{exp}s of the @var{bindings} that follow it, additionally to > being available in @var{body}. > @end defmac > > @defmac pcase-dolist (pattern list) body@dots{} > Execute @var{body} once for each element of @var{list}, on each > iteration performing a destructuring binding of variables in > @var{pattern} to the values of the corresponding subfields of the > element of @var{list}. The bindings are performed as if by > @code{pcase-let}. When @var{pattern} is a simple variable, this ends > up being equivalent to @code{dolist} (@pxref{Iteration}). > @end defmac > > @defmac pcase-setq pattern value@dots{} > Assign values to variables in a @code{setq} form, destructuring each > @var{value} according to its respective @var{pattern}. > @end defmac > > @defmac pcase-lambda lambda-list &rest body > This is like @code{lambda}, but allows each argument to be a pattern. > For instance, here's a simple function that takes a cons cell as the > argument: > > @example > (setq fun > (pcase-lambda (`(,key . ,val)) > (vector key (* val 10)))) > (funcall fun '(foo . 2)) > @result{} [foo 20] > @end example > @end defmac > > > --=20 Marco Antoniotti Somewhere over the Rainbow --000000000000d87b2c0617b10803 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Stefan,

i usually just to= C-h f.=C2=A0 This is what you get from it, in 29.3.

Like `let', but = supports destructuring BINDINGS using `pcase' patterns.
BODY should be a list of expressions, and = BINDINGS should be a list of
bindings of the form (PATTERN EXP).
All EXPs are evaluated first, and then used to perform destructu= ring
bindings by matching e= ach EXP against its respective PATTERN.=C2=A0 Then
BODY is evaluated with those bindings in effect.

Each EXP should match its respective PATTERN (i.e. be o= f structure
compatible to P= ATTERN); a mismatch may signal an error or may go
undetected, binding variables to arbitrary values, s= uch as nil.

=C2=A0 Probably introduced at or before E= macs version 28.1.

The Info doc you p= osted is definitively better.

All the best

MA



On Sat, May 4, 2024= at 5:05=E2=80=AFPM Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> sorry, but I do not think that the cu= rrent doc string and/or the
> manual explains the situation.

Which "current" are you referring to?=C2=A0 The "current&quo= t; manual (in
`master`) has a whole section on "Destructuring with pcase pattern&quo= t;
(see below).

Do you still see room for misunderstanding there?
If so, can you suggest how to change it to make it more clear?


=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan


@node Destructuring with pcase Patterns
@subsection Destructuring with @code{pcase} Patterns
@cindex destructuring with pcase patterns

Pcase patterns not only express a condition on the form of the objects
they can match, but they can also extract sub-fields of those objects.
For example we can extract 2 elements from a list that is the value of
the variable @code{my-list} with the following code:

@example
=C2=A0 (pcase my-list
=C2=A0 =C2=A0 (`(add ,x ,y)=C2=A0 (message "Contains %S and %S" x= y)))
@end example

This will not only extract @code{x} and @code{y} but will additionally
test that @code{my-list} is a list containing exactly 3 elements and
whose first element is the symbol @code{add}.=C2=A0 If any of those tests fail, @code{pcase} will immediately return @code{nil} without calling
@code{message}.

Extraction of multiple values stored in an object is known as
@dfn{destructuring}.=C2=A0 Using @code{pcase} patterns allows you to
perform @dfn{destructuring binding}, which is similar to a local
binding (@pxref{Local Variables}), but gives values to multiple
elements of a variable by extracting those values from an object of
compatible structure.

The macros described in this section use @code{pcase} patterns to
perform destructuring binding.=C2=A0 The condition of the object to be of compatible structure means that the object must match the pattern,
because only then the object's subfields can be extracted.=C2=A0 For example:

@example
=C2=A0 (pcase-let ((`(add ,x ,y) my-list))
=C2=A0 =C2=A0 (message "Contains %S and %S" x y))
@end example

@noindent
does the same as the previous example, except that it directly tries
to extract @code{x} and @code{y} from @code{my-list} without first
verifying if @code{my-list} is a list which has the right number of
elements and has @code{add} as its first element.=C2=A0 The precise
behavior when the object does not actually match the pattern is
undefined, although the body will not be silently skipped: either an
error is signaled or the body is run with some of the variables
potentially bound to arbitrary values like @code{nil}.

The pcase patterns that are useful for destructuring bindings are
generally those described in @ref{Backquote Patterns}, since they
express a specification of the structure of objects that will match.

For an alternative facility for destructuring binding, see
@ref{seq-let}.

@defmac pcase-let bindings body@dots{}
Perform destructuring binding of variables according to
@var{bindings}, and then evaluate @var{body}.

@var{bindings} is a list of bindings of the form @w{@code{(@var{pattern} @var{exp})}}, where @var{exp} is an expression to evaluate and
@var{pattern} is a @code{pcase} pattern.

All @var{exp}s are evaluated first, after which they are matched
against their respective @var{pattern}, introducing new variable
bindings that can then be used inside @var{body}.=C2=A0 The variable
bindings are produced by destructuring binding of elements of
@var{pattern} to the values of the corresponding elements of the
evaluated @var{exp}.

Here's a trivial example:

@example
(pcase-let ((`(,major ,minor)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(split-string "image/p= ng" "/")))
=C2=A0 minor)
=C2=A0 =C2=A0 =C2=A0@result{} "png"
@end example
@end defmac

@defmac pcase-let* bindings body@dots{}
Perform destructuring binding of variables according to
@var{bindings}, and then evaluate @var{body}.

@var{bindings} is a list of bindings of the form @code{(@var{pattern}
@var{exp})}, where @var{exp} is an expression to evaluate and
@var{pattern} is a @code{pcase} pattern.=C2=A0 The variable bindings are produced by destructuring binding of elements of @var{pattern} to the
values of the corresponding elements of the evaluated @var{exp}.

Unlike @code{pcase-let}, but similarly to @code{let*}, each @var{exp}
is matched against its corresponding @var{pattern} before processing
the next element of @var{bindings}, so the variable bindings
introduced in each one of the @var{bindings} are available in the
@var{exp}s of the @var{bindings} that follow it, additionally to
being available in @var{body}.
@end defmac

@defmac pcase-dolist (pattern list) body@dots{}
Execute @var{body} once for each element of @var{list}, on each
iteration performing a destructuring binding of variables in
@var{pattern} to the values of the corresponding subfields of the
element of @var{list}.=C2=A0 The bindings are performed as if by
@code{pcase-let}.=C2=A0 When @var{pattern} is a simple variable, this ends<= br> up being equivalent to @code{dolist} (@pxref{Iteration}).
@end defmac

@defmac pcase-setq pattern value@dots{}
Assign values to variables in a @code{setq} form, destructuring each
@var{value} according to its respective @var{pattern}.
@end defmac

@defmac pcase-lambda lambda-list &rest body
This is like @code{lambda}, but allows each argument to be a pattern.
For instance, here's a simple function that takes a cons cell as the argument:

@example
(setq fun
=C2=A0 =C2=A0 =C2=A0 (pcase-lambda (`(,key . ,val))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (vector key (* val 10))))
(funcall fun '(foo . 2))
=C2=A0 =C2=A0 @result{} [foo 20]
@end example
@end defmac




--
Marco Antonio= tti
Somewhere over the Rainbow
--000000000000d87b2c0617b10803--