unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
@ 2024-06-12  8:40 Mekeor Melire
  2024-06-14  8:42 ` Philip Kaludercic
  0 siblings, 1 reply; 16+ messages in thread
From: Mekeor Melire @ 2024-06-12  8:40 UTC (permalink / raw)
  To: 71503

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).





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-06-12  8:40 bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected Mekeor Melire
@ 2024-06-14  8:42 ` Philip Kaludercic
  2024-06-14 16:08   ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-22  8:37   ` Eli Zaretskii
  0 siblings, 2 replies; 16+ messages in thread
From: Philip Kaludercic @ 2024-06-14  8:42 UTC (permalink / raw)
  To: Mekeor Melire; +Cc: 71503

Mekeor Melire <mekeor@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





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-06-14  8:42 ` Philip Kaludercic
@ 2024-06-14 16:08   ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-06-22  8:37   ` Eli Zaretskii
  1 sibling, 0 replies; 16+ messages in thread
From: Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-06-14 16:08 UTC (permalink / raw)
  To: Philip Kaludercic, Mekeor Melire; +Cc: 71503@debbugs.gnu.org

> 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.








^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-06-14  8:42 ` Philip Kaludercic
  2024-06-14 16:08   ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-06-22  8:37   ` Eli Zaretskii
  2024-07-06  7:38     ` Eli Zaretskii
  1 sibling, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2024-06-22  8:37 UTC (permalink / raw)
  To: Philip Kaludercic, Stefan Monnier; +Cc: mekeor, 71503

> Cc: 71503@debbugs.gnu.org
> From: Philip Kaludercic <philipk@posteo.net>
> Date: Fri, 14 Jun 2024 08:42:25 +0000
> 
> Mekeor Melire <mekeor@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.





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-06-22  8:37   ` Eli Zaretskii
@ 2024-07-06  7:38     ` Eli Zaretskii
  2024-07-20  9:42       ` Eli Zaretskii
  0 siblings, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2024-07-06  7:38 UTC (permalink / raw)
  To: philipk; +Cc: mekeor, monnier, 71503

Ping!

> Cc: mekeor@posteo.de, 71503@debbugs.gnu.org
> Date: Sat, 22 Jun 2024 11:37:02 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> 
> > Cc: 71503@debbugs.gnu.org
> > From: Philip Kaludercic <philipk@posteo.net>
> > Date: Fri, 14 Jun 2024 08:42:25 +0000
> > 
> > Mekeor Melire <mekeor@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.
> 
> 
> 
> 





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-06  7:38     ` Eli Zaretskii
@ 2024-07-20  9:42       ` Eli Zaretskii
  2024-07-20 10:29         ` Philip Kaludercic
  0 siblings, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2024-07-20  9:42 UTC (permalink / raw)
  To: philipk, mekeor; +Cc: monnier, 71503

Ping! Ping!

> Cc: mekeor@posteo.de, monnier@iro.umontreal.ca, 71503@debbugs.gnu.org
> Date: Sat, 06 Jul 2024 10:38:00 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> 
> Ping!
> 
> > Cc: mekeor@posteo.de, 71503@debbugs.gnu.org
> > Date: Sat, 22 Jun 2024 11:37:02 +0300
> > From: Eli Zaretskii <eliz@gnu.org>
> > 
> > > Cc: 71503@debbugs.gnu.org
> > > From: Philip Kaludercic <philipk@posteo.net>
> > > Date: Fri, 14 Jun 2024 08:42:25 +0000
> > > 
> > > Mekeor Melire <mekeor@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.
> > 
> > 
> > 
> > 
> 
> 
> 
> 





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-20  9:42       ` Eli Zaretskii
@ 2024-07-20 10:29         ` Philip Kaludercic
  2024-07-20 10:46           ` Eli Zaretskii
  2024-07-20 14:06           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 16+ messages in thread
From: Philip Kaludercic @ 2024-07-20 10:29 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mekeor, monnier, 71503

[-- Attachment #1: Type: text/plain, Size: 1805 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

> Ping! Ping!
>
>> Cc: mekeor@posteo.de, monnier@iro.umontreal.ca, 71503@debbugs.gnu.org
>> Date: Sat, 06 Jul 2024 10:38:00 +0300
>> From: Eli Zaretskii <eliz@gnu.org>
>> 
>> Ping!
>> 
>> > Cc: mekeor@posteo.de, 71503@debbugs.gnu.org
>> > Date: Sat, 22 Jun 2024 11:37:02 +0300
>> > From: Eli Zaretskii <eliz@gnu.org>
>> > 
>> > > Cc: 71503@debbugs.gnu.org
>> > > From: Philip Kaludercic <philipk@posteo.net>
>> > > Date: Fri, 14 Jun 2024 08:42:25 +0000
>> > > 
>> > > Mekeor Melire <mekeor@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


[-- Attachment #2: Type: text/plain, Size: 920 bytes --]

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 ())

[-- Attachment #3: Type: text/plain, Size: 493 bytes --]


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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-20 10:29         ` Philip Kaludercic
@ 2024-07-20 10:46           ` Eli Zaretskii
  2024-07-21 11:17             ` Philip Kaludercic
  2024-07-20 14:06           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2024-07-20 10:46 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: mekeor, monnier, 71503

> From: Philip Kaludercic <philipk@posteo.net>
> Cc: mekeor@posteo.de,  monnier@iro.umontreal.ca,  71503@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.





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-20 10:29         ` Philip Kaludercic
  2024-07-20 10:46           ` Eli Zaretskii
@ 2024-07-20 14:06           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-07-21 12:39             ` Philip Kaludercic
  1 sibling, 1 reply; 16+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-07-20 14:06 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: mekeor, Eli Zaretskii, 71503

>  (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






^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-20 10:46           ` Eli Zaretskii
@ 2024-07-21 11:17             ` Philip Kaludercic
  2024-07-21 13:33               ` Mekeor Melire
  0 siblings, 1 reply; 16+ messages in thread
From: Philip Kaludercic @ 2024-07-21 11:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mekeor, monnier, 71503

[-- Attachment #1: Type: text/plain, Size: 2797 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

>> From: Philip Kaludercic <philipk@posteo.net>
>> Cc: mekeor@posteo.de,  monnier@iro.umontreal.ca,  71503@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@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:


[-- Attachment #2: Type: text/plain, Size: 1042 bytes --]

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 ())

[-- Attachment #3: Type: text/plain, Size: 59 bytes --]




>         Stefan
>

-- 
	Philip Kaludercic on peregrine

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-20 14:06           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-07-21 12:39             ` Philip Kaludercic
  2024-07-21 13:51               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 16+ messages in thread
From: Philip Kaludercic @ 2024-07-21 12:39 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: mekeor, Eli Zaretskii, 71503

Stefan Monnier <monnier@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





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-21 11:17             ` Philip Kaludercic
@ 2024-07-21 13:33               ` Mekeor Melire
  0 siblings, 0 replies; 16+ messages in thread
From: Mekeor Melire @ 2024-07-21 13:33 UTC (permalink / raw)
  To: 71503; +Cc: Philip Kaludercic, Eli Zaretskii, monnier

2024-07-21 11:17 philipk@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.





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-21 12:39             ` Philip Kaludercic
@ 2024-07-21 13:51               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-04  7:58                 ` Eli Zaretskii
  0 siblings, 1 reply; 16+ messages in thread
From: Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-07-21 13:51 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: mekeor, Eli Zaretskii, 71503

> 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






^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-07-21 13:51               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-04  7:58                 ` Eli Zaretskii
  2024-08-04 14:54                   ` Philip Kaludercic
  0 siblings, 1 reply; 16+ messages in thread
From: Eli Zaretskii @ 2024-08-04  7:58 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: mekeor, philipk, 71503

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

> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: Eli Zaretskii <eliz@gnu.org>,  mekeor@posteo.de,  71503@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
> 
> 





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-08-04  7:58                 ` Eli Zaretskii
@ 2024-08-04 14:54                   ` Philip Kaludercic
  2024-08-04 15:08                     ` Eli Zaretskii
  0 siblings, 1 reply; 16+ messages in thread
From: Philip Kaludercic @ 2024-08-04 14:54 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: mekeor, Stefan Monnier, 71503-done

Eli Zaretskii <eliz@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@iro.umontreal.ca>
>> Cc: Eli Zaretskii <eliz@gnu.org>,  mekeor@posteo.de,  71503@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





^ permalink raw reply	[flat|nested] 16+ messages in thread

* bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected
  2024-08-04 14:54                   ` Philip Kaludercic
@ 2024-08-04 15:08                     ` Eli Zaretskii
  0 siblings, 0 replies; 16+ messages in thread
From: Eli Zaretskii @ 2024-08-04 15:08 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: mekeor, monnier, 71503-done

> From: Philip Kaludercic <philipk@posteo.net>
> Cc: Stefan Monnier <monnier@iro.umontreal.ca>,  mekeor@posteo.de,
>   71503-done@debbugs.gnu.org
> Date: Sun, 04 Aug 2024 14:54:44 +0000
> 
> Eli Zaretskii <eliz@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!





^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2024-08-04 15:08 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-12  8:40 bug#71503: 30.0.50; pcase-lambda (with "and" and "guard") does not work as expected Mekeor Melire
2024-06-14  8:42 ` Philip Kaludercic
2024-06-14 16:08   ` Drew Adams via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-06-22  8:37   ` Eli Zaretskii
2024-07-06  7:38     ` Eli Zaretskii
2024-07-20  9:42       ` Eli Zaretskii
2024-07-20 10:29         ` Philip Kaludercic
2024-07-20 10:46           ` Eli Zaretskii
2024-07-21 11:17             ` Philip Kaludercic
2024-07-21 13:33               ` Mekeor Melire
2024-07-20 14:06           ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-07-21 12:39             ` Philip Kaludercic
2024-07-21 13:51               ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-04  7:58                 ` Eli Zaretskii
2024-08-04 14:54                   ` Philip Kaludercic
2024-08-04 15:08                     ` Eli Zaretskii

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).