GNU bug report logs - #71503
30.0.50; pcase-lambda (with "and" and "guard") does not work as expected

Previous Next

Package: emacs;

Reported by: Mekeor Melire <mekeor <at> posteo.de>

Date: Wed, 12 Jun 2024 08:42:01 UTC

Severity: normal

Found in version 30.0.50

Done: Philip Kaludercic <philipk <at> posteo.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 71503 in the body.
You can then email your comments to 71503 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Wed, 12 Jun 2024 08:42:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Mekeor Melire <mekeor <at> posteo.de>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Wed, 12 Jun 2024 08:42:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Mekeor Melire <mekeor <at> posteo.de>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.0.50; pcase-lambda (with "and" and "guard") does not work as
 expected
Date: Wed, 12 Jun 2024 08:40:54 +0000
I was expecting these two expressions to evaluate to the same value.
First, we call `pcase' on a value with a pattern involving `and' and
`guard':

    (pcase "value"
      ((and v (guard (string= "not-value" v))) v))
    ;; => nil

Second, let's use the same value and pattern, but this time using
`pcase-lambda':

    (funcall
      (pcase-lambda
        ((and v (guard (string= "not-value" v)))) v)
      "value")
    ;; => "value"

Am I missing something or is this a bug?

In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
3.24.41, cairo version 1.16.0).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Fri, 14 Jun 2024 08:43:02 GMT) Full text and rfc822 format available.

Message #8 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Mekeor Melire <mekeor <at> posteo.de>
Cc: 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Fri, 14 Jun 2024 08:42:25 +0000
Mekeor Melire <mekeor <at> posteo.de> writes:

> I was expecting these two expressions to evaluate to the same value.
> First, we call `pcase' on a value with a pattern involving `and' and
> `guard':
>
>     (pcase "value"
>       ((and v (guard (string= "not-value" v))) v))
>     ;; => nil
>
> Second, let's use the same value and pattern, but this time using
> `pcase-lambda':
>
>     (funcall
>       (pcase-lambda
>         ((and v (guard (string= "not-value" v)))) v)
>       "value")
>     ;; => "value"
>
> Am I missing something or is this a bug?

The difference is that pcase-lambda doesn't do case-distinction, but
just pattern matching/destruncting.  So if the pattern-matching fails,
then the variable is just not bound, instead of the entire expression
falling back to returning no value/nil.  I am guessing you wanted to
have something like Scheme's `case-lambda'[0]?  Or we could clarify this
point in the docstring.

> In GNU Emacs 30.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version
> 3.24.41, cairo version 1.16.0).

[0] https://index.scheme.org/filterset/r7rs_small/%28scheme%2520case-lambda%29/case-lambda

-- 
	Philip Kaludercic on peregrine




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Fri, 14 Jun 2024 16:09:02 GMT) Full text and rfc822 format available.

Message #11 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Philip Kaludercic <philipk <at> posteo.net>, Mekeor Melire <mekeor <at> posteo.de>
Cc: "71503 <at> debbugs.gnu.org" <71503 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#71503: 30.0.50; pcase-lambda (with "and" and
 "guard") does not work as expected
Date: Fri, 14 Jun 2024 16:08:41 +0000
> The difference is that pcase-lambda
> doesn't do case-distinction, but
> just pattern matching/destruncting.

Unless I'm mistaken, this confusion has
surfaced several times now...

Is it really a good idea to call this
"pcase-" <anything>, if it has nothing to
do with case distinction, i.e., control
flow?

Why not a name that suggests destructuring
or pattern-matching, and binding?  Common
Lisp at least calls its (weaker) construct
`destructuring-bind' - pretty clear.







Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 22 Jun 2024 08:38:02 GMT) Full text and rfc822 format available.

Message #14 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Philip Kaludercic <philipk <at> posteo.net>,
 Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: mekeor <at> posteo.de, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50;
 pcase-lambda (with "and" and "guard") does not work as expected
Date: Sat, 22 Jun 2024 11:37:02 +0300
> Cc: 71503 <at> debbugs.gnu.org
> From: Philip Kaludercic <philipk <at> posteo.net>
> Date: Fri, 14 Jun 2024 08:42:25 +0000
> 
> Mekeor Melire <mekeor <at> posteo.de> writes:
> 
> > I was expecting these two expressions to evaluate to the same value.
> > First, we call `pcase' on a value with a pattern involving `and' and
> > `guard':
> >
> >     (pcase "value"
> >       ((and v (guard (string= "not-value" v))) v))
> >     ;; => nil
> >
> > Second, let's use the same value and pattern, but this time using
> > `pcase-lambda':
> >
> >     (funcall
> >       (pcase-lambda
> >         ((and v (guard (string= "not-value" v)))) v)
> >       "value")
> >     ;; => "value"
> >
> > Am I missing something or is this a bug?
> 
> The difference is that pcase-lambda doesn't do case-distinction, but
> just pattern matching/destruncting.  So if the pattern-matching fails,
> then the variable is just not bound, instead of the entire expression
> falling back to returning no value/nil.  I am guessing you wanted to
> have something like Scheme's `case-lambda'[0]?  Or we could clarify this
> point in the docstring.

Would you mind suggesting a clarification for the doc string (and the
ELisp manual as well)?

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 06 Jul 2024 07:39:02 GMT) Full text and rfc822 format available.

Message #17 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: philipk <at> posteo.net
Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50;
 pcase-lambda (with "and" and "guard") does not work as expected
Date: Sat, 06 Jul 2024 10:38:00 +0300
Ping!

> Cc: mekeor <at> posteo.de, 71503 <at> debbugs.gnu.org
> Date: Sat, 22 Jun 2024 11:37:02 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> > Cc: 71503 <at> debbugs.gnu.org
> > From: Philip Kaludercic <philipk <at> posteo.net>
> > Date: Fri, 14 Jun 2024 08:42:25 +0000
> > 
> > Mekeor Melire <mekeor <at> posteo.de> writes:
> > 
> > > I was expecting these two expressions to evaluate to the same value.
> > > First, we call `pcase' on a value with a pattern involving `and' and
> > > `guard':
> > >
> > >     (pcase "value"
> > >       ((and v (guard (string= "not-value" v))) v))
> > >     ;; => nil
> > >
> > > Second, let's use the same value and pattern, but this time using
> > > `pcase-lambda':
> > >
> > >     (funcall
> > >       (pcase-lambda
> > >         ((and v (guard (string= "not-value" v)))) v)
> > >       "value")
> > >     ;; => "value"
> > >
> > > Am I missing something or is this a bug?
> > 
> > The difference is that pcase-lambda doesn't do case-distinction, but
> > just pattern matching/destruncting.  So if the pattern-matching fails,
> > then the variable is just not bound, instead of the entire expression
> > falling back to returning no value/nil.  I am guessing you wanted to
> > have something like Scheme's `case-lambda'[0]?  Or we could clarify this
> > point in the docstring.
> 
> Would you mind suggesting a clarification for the doc string (and the
> ELisp manual as well)?
> 
> Thanks.
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 20 Jul 2024 09:43:02 GMT) Full text and rfc822 format available.

Message #20 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: philipk <at> posteo.net, mekeor <at> posteo.de
Cc: monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50;
 pcase-lambda (with "and" and "guard") does not work as expected
Date: Sat, 20 Jul 2024 12:42:43 +0300
Ping! Ping!

> Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
> Date: Sat, 06 Jul 2024 10:38:00 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> Ping!
> 
> > Cc: mekeor <at> posteo.de, 71503 <at> debbugs.gnu.org
> > Date: Sat, 22 Jun 2024 11:37:02 +0300
> > From: Eli Zaretskii <eliz <at> gnu.org>
> > 
> > > Cc: 71503 <at> debbugs.gnu.org
> > > From: Philip Kaludercic <philipk <at> posteo.net>
> > > Date: Fri, 14 Jun 2024 08:42:25 +0000
> > > 
> > > Mekeor Melire <mekeor <at> posteo.de> writes:
> > > 
> > > > I was expecting these two expressions to evaluate to the same value.
> > > > First, we call `pcase' on a value with a pattern involving `and' and
> > > > `guard':
> > > >
> > > >     (pcase "value"
> > > >       ((and v (guard (string= "not-value" v))) v))
> > > >     ;; => nil
> > > >
> > > > Second, let's use the same value and pattern, but this time using
> > > > `pcase-lambda':
> > > >
> > > >     (funcall
> > > >       (pcase-lambda
> > > >         ((and v (guard (string= "not-value" v)))) v)
> > > >       "value")
> > > >     ;; => "value"
> > > >
> > > > Am I missing something or is this a bug?
> > > 
> > > The difference is that pcase-lambda doesn't do case-distinction, but
> > > just pattern matching/destruncting.  So if the pattern-matching fails,
> > > then the variable is just not bound, instead of the entire expression
> > > falling back to returning no value/nil.  I am guessing you wanted to
> > > have something like Scheme's `case-lambda'[0]?  Or we could clarify this
> > > point in the docstring.
> > 
> > Would you mind suggesting a clarification for the doc string (and the
> > ELisp manual as well)?
> > 
> > Thanks.
> > 
> > 
> > 
> > 
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 20 Jul 2024 10:31:02 GMT) Full text and rfc822 format available.

Message #23 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sat, 20 Jul 2024 10:29:55 +0000
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

> Ping! Ping!
>
>> Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
>> Date: Sat, 06 Jul 2024 10:38:00 +0300
>> From: Eli Zaretskii <eliz <at> gnu.org>
>> 
>> Ping!
>> 
>> > Cc: mekeor <at> posteo.de, 71503 <at> debbugs.gnu.org
>> > Date: Sat, 22 Jun 2024 11:37:02 +0300
>> > From: Eli Zaretskii <eliz <at> gnu.org>
>> > 
>> > > Cc: 71503 <at> debbugs.gnu.org
>> > > From: Philip Kaludercic <philipk <at> posteo.net>
>> > > Date: Fri, 14 Jun 2024 08:42:25 +0000
>> > > 
>> > > Mekeor Melire <mekeor <at> posteo.de> writes:
>> > > 
>> > > > I was expecting these two expressions to evaluate to the same value.
>> > > > First, we call `pcase' on a value with a pattern involving `and' and
>> > > > `guard':
>> > > >
>> > > >     (pcase "value"
>> > > >       ((and v (guard (string= "not-value" v))) v))
>> > > >     ;; => nil
>> > > >
>> > > > Second, let's use the same value and pattern, but this time using
>> > > > `pcase-lambda':
>> > > >
>> > > >     (funcall
>> > > >       (pcase-lambda
>> > > >         ((and v (guard (string= "not-value" v)))) v)
>> > > >       "value")
>> > > >     ;; => "value"
>> > > >
>> > > > Am I missing something or is this a bug?
>> > > 
>> > > The difference is that pcase-lambda doesn't do case-distinction, but
>> > > just pattern matching/destruncting.  So if the pattern-matching fails,
>> > > then the variable is just not bound, instead of the entire expression
>> > > falling back to returning no value/nil.  I am guessing you wanted to
>> > > have something like Scheme's `case-lambda'[0]?  Or we could clarify this
>> > > point in the docstring.
>> > 
>> > Would you mind suggesting a clarification for the doc string (and the
>> > ELisp manual as well)?

Sorry, I didn't realise you were pining me.  I was thinking of something
like

[Message part 2 (text/plain, inline)]
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 5a7f3995311..f546ba34c7c 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -241,9 +241,10 @@ pcase-exhaustive
 ;;;###autoload
 (defmacro pcase-lambda (lambda-list &rest body)
   "Like `lambda' but allow each argument to be a pattern.
-I.e. accepts the usual &optional and &rest keywords, but every
-formal argument can be any pattern accepted by `pcase' (a mere
-variable name being but a special case of it)."
+I.e. accepts the usual &optional and &rest keywords, but every formal
+argument can be any pattern accepted by `pcase' (a mere variable name
+being but a special case of it).  Keep in mind that BODY is always
+evaluated, regardless of whether the argument-patterns match or not."
   (declare (doc-string 2) (indent defun)
            (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
   (let* ((bindings ())
[Message part 3 (text/plain, inline)]
but now I notice that `pcase-let*' documents that all expressions should
match,

  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.

Since `pcase-lambda' inherits these semantics we would have to propagate
this promise -- or be more specific about what happens, e.g. binding
values to nil.

>> > Thanks.

-- 
	Philip Kaludercic on peregrine

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 20 Jul 2024 10:47:02 GMT) Full text and rfc822 format available.

Message #26 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sat, 20 Jul 2024 13:46:45 +0300
> From: Philip Kaludercic <philipk <at> posteo.net>
> Cc: mekeor <at> posteo.de,  monnier <at> iro.umontreal.ca,  71503 <at> debbugs.gnu.org
> Date: Sat, 20 Jul 2024 10:29:55 +0000
> 
> >> > > The difference is that pcase-lambda doesn't do case-distinction, but
> >> > > just pattern matching/destruncting.  So if the pattern-matching fails,
> >> > > then the variable is just not bound, instead of the entire expression
> >> > > falling back to returning no value/nil.  I am guessing you wanted to
> >> > > have something like Scheme's `case-lambda'[0]?  Or we could clarify this
> >> > > point in the docstring.
> >> > 
> >> > Would you mind suggesting a clarification for the doc string (and the
> >> > ELisp manual as well)?
> 
> Sorry, I didn't realise you were pining me.  I was thinking of something
> like
> 
> diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
> index 5a7f3995311..f546ba34c7c 100644
> --- a/lisp/emacs-lisp/pcase.el
> +++ b/lisp/emacs-lisp/pcase.el
> @@ -241,9 +241,10 @@ pcase-exhaustive
>  ;;;###autoload
>  (defmacro pcase-lambda (lambda-list &rest body)
>    "Like `lambda' but allow each argument to be a pattern.
> -I.e. accepts the usual &optional and &rest keywords, but every
> -formal argument can be any pattern accepted by `pcase' (a mere
> -variable name being but a special case of it)."
> +I.e. accepts the usual &optional and &rest keywords, but every formal
> +argument can be any pattern accepted by `pcase' (a mere variable name
> +being but a special case of it).  Keep in mind that BODY is always
> +evaluated, regardless of whether the argument-patterns match or not."
>    (declare (doc-string 2) (indent defun)
>             (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
>    (let* ((bindings ())
> 
> but now I notice that `pcase-let*' documents that all expressions should
> match,
> 
>   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.
> 
> Since `pcase-lambda' inherits these semantics we would have to propagate
> this promise -- or be more specific about what happens, e.g. binding
> values to nil.

Thanks.  If this still can be fixed by some documentation changes, I'd
prefer to do that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sat, 20 Jul 2024 14:07:01 GMT) Full text and rfc822 format available.

Message #29 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: mekeor <at> posteo.de, Eli Zaretskii <eliz <at> gnu.org>, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sat, 20 Jul 2024 10:06:18 -0400
>  (defmacro pcase-lambda (lambda-list &rest body)
>    "Like `lambda' but allow each argument to be a pattern.
> -I.e. accepts the usual &optional and &rest keywords, but every
> -formal argument can be any pattern accepted by `pcase' (a mere
> -variable name being but a special case of it)."
> +I.e. accepts the usual &optional and &rest keywords, but every formal
> +argument can be any pattern accepted by `pcase' (a mere variable name
> +being but a special case of it).  Keep in mind that BODY is always
> +evaluated, regardless of whether the argument-patterns match or not."
>    (declare (doc-string 2) (indent defun)
>             (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
>    (let* ((bindings ())

I tend to call "any pattern accepted by `pcase'" a "Pcase pattern".
More importantly, we should refer to `pcase-let` rather than to
`pcase` here and we should likely use the term "destructuring (binding)".


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 21 Jul 2024 11:18:01 GMT) Full text and rfc822 format available.

Message #32 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 21 Jul 2024 11:17:05 +0000
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Philip Kaludercic <philipk <at> posteo.net>
>> Cc: mekeor <at> posteo.de,  monnier <at> iro.umontreal.ca,  71503 <at> debbugs.gnu.org
>> Date: Sat, 20 Jul 2024 10:29:55 +0000
>> 
>> >> > > The difference is that pcase-lambda doesn't do case-distinction, but
>> >> > > just pattern matching/destruncting.  So if the pattern-matching fails,
>> >> > > then the variable is just not bound, instead of the entire expression
>> >> > > falling back to returning no value/nil.  I am guessing you wanted to
>> >> > > have something like Scheme's `case-lambda'[0]?  Or we could
>> >> > > clarify this
>> >> > > point in the docstring.
>> >> > 
>> >> > Would you mind suggesting a clarification for the doc string (and the
>> >> > ELisp manual as well)?
>> 
>> Sorry, I didn't realise you were pining me.  I was thinking of something
>> like
>> 
>> diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
>> index 5a7f3995311..f546ba34c7c 100644
>> --- a/lisp/emacs-lisp/pcase.el
>> +++ b/lisp/emacs-lisp/pcase.el
>> @@ -241,9 +241,10 @@ pcase-exhaustive
>>  ;;;###autoload
>>  (defmacro pcase-lambda (lambda-list &rest body)
>>    "Like `lambda' but allow each argument to be a pattern.
>> -I.e. accepts the usual &optional and &rest keywords, but every
>> -formal argument can be any pattern accepted by `pcase' (a mere
>> -variable name being but a special case of it)."
>> +I.e. accepts the usual &optional and &rest keywords, but every formal
>> +argument can be any pattern accepted by `pcase' (a mere variable name
>> +being but a special case of it).  Keep in mind that BODY is always
>> +evaluated, regardless of whether the argument-patterns match or not."
>>    (declare (doc-string 2) (indent defun)
>>             (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
>>    (let* ((bindings ())
>> 
>> but now I notice that `pcase-let*' documents that all expressions should
>> match,
>> 
>>   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.
>> 
>> Since `pcase-lambda' inherits these semantics we would have to propagate
>> this promise -- or be more specific about what happens, e.g. binding
>> values to nil.
>
> Thanks.  If this still can be fixed by some documentation changes, I'd
> prefer to do that.

In that case I think it would be better to stick to a warning like the
one in `pcase-let*'..

Stefan Monnier <monnier <at> iro.umontreal.ca> writes:


[...]

> I tend to call "any pattern accepted by `pcase'" a "Pcase pattern".
> More importantly, we should refer to `pcase-let` rather than to
> `pcase` here and we should likely use the term "destructuring (binding)".

What do you think of:

[Message part 2 (text/plain, inline)]
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 5a7f3995311..fd6b0c8db5c 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -241,9 +241,14 @@ pcase-exhaustive
 ;;;###autoload
 (defmacro pcase-lambda (lambda-list &rest body)
   "Like `lambda' but allow each argument to be a pattern.
-I.e. accepts the usual &optional and &rest keywords, but every
-formal argument can be any pattern accepted by `pcase' (a mere
-variable name being but a special case of it)."
+I.e. accepts the usual &optional and &rest keywords, but every formal
+argument can be any pattern destructed by `pcase-let' (a mere variable
+name being but a special case of it).
+
+Each argument should match its respective pattern in the parameter
+list (i.e. be of a compatible structure); a mismatch may signal an error
+or may go undetected, binding arguments to arbitrary values, such as
+nil."
   (declare (doc-string 2) (indent defun)
            (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
   (let* ((bindings ())
[Message part 3 (text/plain, inline)]


>         Stefan
>

-- 
	Philip Kaludercic on peregrine

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 21 Jul 2024 12:40:02 GMT) Full text and rfc822 format available.

Message #35 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: mekeor <at> posteo.de, Eli Zaretskii <eliz <at> gnu.org>, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 21 Jul 2024 12:39:00 +0000
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>>  (defmacro pcase-lambda (lambda-list &rest body)
>>    "Like `lambda' but allow each argument to be a pattern.
>> -I.e. accepts the usual &optional and &rest keywords, but every
>> -formal argument can be any pattern accepted by `pcase' (a mere
>> -variable name being but a special case of it)."
>> +I.e. accepts the usual &optional and &rest keywords, but every formal
>> +argument can be any pattern accepted by `pcase' (a mere variable name
>> +being but a special case of it).  Keep in mind that BODY is always
>> +evaluated, regardless of whether the argument-patterns match or not."
>>    (declare (doc-string 2) (indent defun)
>>             (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
>>    (let* ((bindings ())
>
> I tend to call "any pattern accepted by `pcase'" a "Pcase pattern".
> More importantly, we should refer to `pcase-let` rather than to
> `pcase` here and we should likely use the term "destructuring (binding)".

Another confusing behaviour that we should document is that in

(let ((a nil))
  (funcall
   (pcase-lambda (a (and (guard a) b))
     (list a b))
   1 2))

I would expect that the (guard a) would use the nil binding from the
`let' form, but instead it is ignored and b is bound to 2.  I am not
sure if this is related to the "destructing" point or not.

>
>
>         Stefan
>

-- 
	Philip Kaludercic on peregrine




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 21 Jul 2024 13:34:01 GMT) Full text and rfc822 format available.

Message #38 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Mekeor Melire <mekeor <at> posteo.de>
To: 71503 <at> debbugs.gnu.org
Cc: Philip Kaludercic <philipk <at> posteo.net>, Eli Zaretskii <eliz <at> gnu.org>,
 monnier <at> iro.umontreal.ca
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 21 Jul 2024 13:33:18 +0000
2024-07-21 11:17 philipk <at> posteo.net:

> What do you think of:

>    "Like `lambda' but allow each argument to be a pattern.
> -I.e. accepts the usual &optional and &rest keywords, but every
> -formal argument can be any pattern accepted by `pcase' (a mere
> -variable name being but a special case of it)."
> +I.e. accepts the usual &optional and &rest keywords, but every formal
> +argument can be any pattern destructed by `pcase-let' (a mere variable
> +name being but a special case of it).
> +
> +Each argument should match its respective pattern in the parameter
> +list (i.e. be of a compatible structure); a mismatch may signal an error
> +or may go undetected, binding arguments to arbitrary values, such as
> +nil."
>    (declare (doc-string 2) (indent defun)
>             (debug (&define (&rest pcase-PAT) lambda-doc def-body)))
>    (let* ((bindings ())

Being the submitter of this bug-report, this suggested change would
indeed fix the problem for me and would avoid confusion.  I thus support
this change and thank y'all for your efforts.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 21 Jul 2024 13:52:01 GMT) Full text and rfc822 format available.

Message #41 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: mekeor <at> posteo.de, Eli Zaretskii <eliz <at> gnu.org>, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 21 Jul 2024 09:51:04 -0400
> Another confusing behaviour that we should document is that in
>
> (let ((a nil))
>   (funcall
>    (pcase-lambda (a (and (guard a) b))
>      (list a b))
>    1 2))
>
> I would expect that the (guard a) would use the nil binding from the
> `let' form, but instead it is ignored and b is bound to 2.  I am not
> sure if this is related to the "destructing" point or not.

It most definitely is: the `guard` controls here whether the pattern
matches or not, but since it's a destructuring match `pcase` takes it
for granted that the pattern does match, so the guard is ignored.

What might be more confusing is the scoping, e.g.:

    (macroexpand '(pcase-lambda ((and (guard a) b) a) (FOO)))
=>
    #'(lambda (arg0 a) (pcase-let* (((and (guard a) b) arg0)) (FOO)))

so the `a` in the guard refers to the argument that follows rather than
to a surrounding `a` binding.


        Stefan





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 04 Aug 2024 07:59:02 GMT) Full text and rfc822 format available.

Message #44 received at 71503 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: mekeor <at> posteo.de, philipk <at> posteo.net, 71503 <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 04 Aug 2024 10:58:00 +0300
Ping!  can we please make progress with this issue, one way or
another?

> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz <at> gnu.org>,  mekeor <at> posteo.de,  71503 <at> debbugs.gnu.org
> Date: Sun, 21 Jul 2024 09:51:04 -0400
> 
> > Another confusing behaviour that we should document is that in
> >
> > (let ((a nil))
> >   (funcall
> >    (pcase-lambda (a (and (guard a) b))
> >      (list a b))
> >    1 2))
> >
> > I would expect that the (guard a) would use the nil binding from the
> > `let' form, but instead it is ignored and b is bound to 2.  I am not
> > sure if this is related to the "destructing" point or not.
> 
> It most definitely is: the `guard` controls here whether the pattern
> matches or not, but since it's a destructuring match `pcase` takes it
> for granted that the pattern does match, so the guard is ignored.
> 
> What might be more confusing is the scoping, e.g.:
> 
>     (macroexpand '(pcase-lambda ((and (guard a) b) a) (FOO)))
> =>
>     #'(lambda (arg0 a) (pcase-let* (((and (guard a) b) arg0)) (FOO)))
> 
> so the `a` in the guard refers to the argument that follows rather than
> to a surrounding `a` binding.
> 
> 
>         Stefan
> 
> 




Reply sent to Philip Kaludercic <philipk <at> posteo.net>:
You have taken responsibility. (Sun, 04 Aug 2024 14:56:02 GMT) Full text and rfc822 format available.

Notification sent to Mekeor Melire <mekeor <at> posteo.de>:
bug acknowledged by developer. (Sun, 04 Aug 2024 14:56:03 GMT) Full text and rfc822 format available.

Message #49 received at 71503-done <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: mekeor <at> posteo.de, Stefan Monnier <monnier <at> iro.umontreal.ca>,
 71503-done <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 04 Aug 2024 14:54:44 +0000
Eli Zaretskii <eliz <at> gnu.org> writes:

> Ping!  can we please make progress with this issue, one way or
> another?

I've pushed the change in 0756f308 that Mekeor previously acknowledged
as fine.  Closing.

>> From: Stefan Monnier <monnier <at> iro.umontreal.ca>
>> Cc: Eli Zaretskii <eliz <at> gnu.org>,  mekeor <at> posteo.de,  71503 <at> debbugs.gnu.org
>> Date: Sun, 21 Jul 2024 09:51:04 -0400
>> 
>> > Another confusing behaviour that we should document is that in
>> >
>> > (let ((a nil))
>> >   (funcall
>> >    (pcase-lambda (a (and (guard a) b))
>> >      (list a b))
>> >    1 2))
>> >
>> > I would expect that the (guard a) would use the nil binding from the
>> > `let' form, but instead it is ignored and b is bound to 2.  I am not
>> > sure if this is related to the "destructing" point or not.
>> 
>> It most definitely is: the `guard` controls here whether the pattern
>> matches or not, but since it's a destructuring match `pcase` takes it
>> for granted that the pattern does match, so the guard is ignored.
>> 
>> What might be more confusing is the scoping, e.g.:
>> 
>>     (macroexpand '(pcase-lambda ((and (guard a) b) a) (FOO)))
>> =>
>>     #'(lambda (arg0 a) (pcase-let* (((and (guard a) b) arg0)) (FOO)))
>> 
>> so the `a` in the guard refers to the argument that follows rather than
>> to a surrounding `a` binding.
>> 
>> 
>>         Stefan
>> 
>> 

-- 
	Philip Kaludercic on peregrine




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#71503; Package emacs. (Sun, 04 Aug 2024 15:09:02 GMT) Full text and rfc822 format available.

Message #52 received at 71503-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Philip Kaludercic <philipk <at> posteo.net>
Cc: mekeor <at> posteo.de, monnier <at> iro.umontreal.ca, 71503-done <at> debbugs.gnu.org
Subject: Re: bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does
 not work as expected
Date: Sun, 04 Aug 2024 18:08:13 +0300
> From: Philip Kaludercic <philipk <at> posteo.net>
> Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>,  mekeor <at> posteo.de,
>   71503-done <at> debbugs.gnu.org
> Date: Sun, 04 Aug 2024 14:54:44 +0000
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > Ping!  can we please make progress with this issue, one way or
> > another?
> 
> I've pushed the change in 0756f308 that Mekeor previously acknowledged
> as fine.  Closing.

Thanks!




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Mon, 02 Sep 2024 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 167 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.