GNU bug report logs - #20268
25.0.50; pcase-lambda broken

Previous Next

Package: emacs;

Reported by: Leo Liu <sdl.web <at> gmail.com>

Date: Tue, 7 Apr 2015 07:43:02 UTC

Severity: wishlist

Found in version 25.0.50

Fixed in version 29.1

Done: Lars Ingebrigtsen <larsi <at> gnus.org>

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 20268 in the body.
You can then email your comments to 20268 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 monnier <at> iro.umontreal.ca, bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Tue, 07 Apr 2015 07:43:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Leo Liu <sdl.web <at> gmail.com>:
New bug report received and forwarded. Copy sent to monnier <at> iro.umontreal.ca, bug-gnu-emacs <at> gnu.org. (Tue, 07 Apr 2015 07:43:02 GMT) Full text and rfc822 format available.

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

From: Leo Liu <sdl.web <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 25.0.50; pcase-lambda broken
Date: Tue, 07 Apr 2015 15:42:32 +0800
After the recent rewrite, pcase-lambda is broken. For example, eval the
following to get 46422 instead of the correct value 65535.

   (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
            '([min_bin_vheap_size 46422]
              [min_heap_size 233]
              [fullsweep_after 65535]
              [minor_gcs 40]))

Thanks,
Leo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 01:02:02 GMT) Full text and rfc822 format available.

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

From: Leo Liu <sdl.web <at> gmail.com>
To: 20268 <at> debbugs.gnu.org
Cc: Stefan Monnier <monnier <at> iro.umontreal.ca>
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 09:01:13 +0800
Forgive me to rely here. None of our messages shown up in bug#19670.

> After recent rewrite of pcase-lambda I am seeing:

> (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
>         '([min_bin_vheap_size 46422]
>           [min_heap_size 233]
>           [fullsweep_after 65535]
>
>           [minor_gcs 10]))
>
> Indeed, that's the semantics I chose.
> The previous semantics was for the function to do nothing and return nil
> if the arg doesn't match.  The new semantics is the same as the one used
> by pcase-let.  It's not without its fault of course, but at least it does
> correspond to the usual idea of "destructuring" and generates more
> efficient code.

I don't mind new semantics but I want to make sense of it so as to use
it with confidence. What I am seeing is:

(funcall (pcase-lambda (`[fullsweep_after ,v]) v) [min_bin_vheap_size 46422])

=> 46422

That doesn't make sense to me. Could you explain why this is the right
thing?

> I think if you prefer to return nil, then the macro should look like

>   (pcase-lambda ((`[fullsweep_after ,v]) v))

> which would then naturally let you add additional cases like

>   (pcase-lambda ((`[fullsweep_after ,v]) v)
>                 ((`[min_heap_size ,v]) (/ v 2)))

I didn't choose the multiple-clause version because it is a cheap
shortcut for (lambda (...) (pcase ... ...)).

The single-clause pcase-lambda makes a lot of higher-order functions fun
to use and that is where I am reaping the benefits.

> Admittedly, for the current pcase-lambda (and pcase-let) macro, the
> pcase.el code should be refined so as to emit a warning when it ends up
> ignoring a constant like `fullsweep_after' above.

Yes, I am having a lot of trouble understanding and using pcase-let*
except for trivial cases. I don't want the same thing to happen to
pcase-lambda.

>        Stefan

Thanks,
Leo




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 02:15:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Leo Liu <sdl.web <at> gmail.com>
Cc: 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Tue, 07 Apr 2015 22:14:29 -0400
> After the recent rewrite, pcase-lambda is broken. For example, eval the
> following to get 46422 instead of the correct value 65535.

>    (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
>             '([min_bin_vheap_size 46422]
>               [min_heap_size 233]
>               [fullsweep_after 65535]
>               [minor_gcs 40]))

Indeed, that's the semantics I chose.
The previous semantics was for the function to do nothing and return nil
if the arg doesn't match.  The new semantics is the same as the one used
by pcase-let.  It's not without its fault of course, but at least it does
correspond to the usual idea of "destructuring" and generates more
efficient code.

I think if you prefer to return nil, then the macro should look like

   (pcase-lambda ((`[fullsweep_after ,v]) v))

which would then naturally let you add additional cases like

   (pcase-lambda ((`[fullsweep_after ,v]) v)
                 ((`[min_heap_size ,v]) (/ v 2)))

Admittedly, for the current pcase-lambda (and pcase-let) macro, the
pcase.el code should be refined so as to emit a warning when it ends up
ignoring a constant like `fullsweep_after' above.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 13:24:01 GMT) Full text and rfc822 format available.

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

From: Andy Moreton <andrewjmoreton <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 14:22:46 +0100
On Tue 07 Apr 2015, Stefan Monnier wrote:

>> After the recent rewrite, pcase-lambda is broken. For example, eval the
>> following to get 46422 instead of the correct value 65535.
>
>>    (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
>>             '([min_bin_vheap_size 46422]
>>               [min_heap_size 233]
>>               [fullsweep_after 65535]
>>               [minor_gcs 40]))
>
> Indeed, that's the semantics I chose.
> The previous semantics was for the function to do nothing and return nil
> if the arg doesn't match.  The new semantics is the same as the one used
> by pcase-let.  It's not without its fault of course, but at least it does
> correspond to the usual idea of "destructuring" and generates more
> efficient code.

Please improve the documentation for the pcase macros:

 a) The elisp manual has reference documentation for pcase, but it is
    confusing and short on examples. The first example would be clearer
    if it was more like the second example, by showing some example
    forms that invoke pcase and the result of evaluating them.

    The description would flow more logically if the second example
    followed the reference that describes the allowed patterns, and 
    included an example of each type of pattern.

 b) Add meaningful help strings for pcase-lambda, pcase-let* and
    pcase-let. The existing help strings all say that these constructs
    are "the same as another thing only different" which only serves to
    obscure what they do. A user should be able to discern what the
    interface contract is without reading the implementation. A short
    motivating example for each macro would be helpful.

These improvements would make code using the pcase macros more readable,
and aid understanding of the intended semantics.

    AndyM





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 14:37:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Leo Liu <sdl.web <at> gmail.com>
Cc: 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 10:35:53 -0400
> I don't mind new semantics but I want to make sense of it so as to use
> it with confidence. What I am seeing is:
> (funcall (pcase-lambda (`[fullsweep_after ,v]) v) [min_bin_vheap_size 46422])

When destructuring (as opposed to performing case-analysis), pcase.el
takes as a given that the pattern does match, so the pattern is
basically only used to decide from where to extract the information to
bind the variables.  So the following patterns are equivalent:

   `[fullsweep_after ,v]

   `[,_ ,v]

   `[,(pred foo) ,v]

If you want to test that the pattern matches, that means someone needs
to decide what happens when the pattern doesn't match.  The previous
behavior was to "do nothing and return nil", which is too arbitrary for
my taste, so if you want that, you need to write it

   (lambda (x) (pcase (`[fullsweep_after ,v] v)))


-- Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 15:09:02 GMT) Full text and rfc822 format available.

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

From: Philipp Stephani <p.stephani2 <at> gmail.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>, Leo Liu <sdl.web <at> gmail.com>
Cc: 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 15:08:36 +0000
[Message part 1 (text/plain, inline)]
Stefan Monnier <monnier <at> iro.umontreal.ca> schrieb am Mi., 8. Apr. 2015 um
04:15 Uhr:

> > After the recent rewrite, pcase-lambda is broken. For example, eval the
> > following to get 46422 instead of the correct value 65535.
>
> >    (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
> >             '([min_bin_vheap_size 46422]
> >               [min_heap_size 233]
> >               [fullsweep_after 65535]
> >               [minor_gcs 40]))
>
> Indeed, that's the semantics I chose.
> The previous semantics was for the function to do nothing and return nil
> if the arg doesn't match.  The new semantics is the same as the one used
> by pcase-let.  It's not without its fault of course, but at least it does
> correspond to the usual idea of "destructuring" and generates more
> efficient code.
>
> I think if you prefer to return nil, then the macro should look like
>
>    (pcase-lambda ((`[fullsweep_after ,v]) v))
>
> which would then naturally let you add additional cases like
>
>    (pcase-lambda ((`[fullsweep_after ,v]) v)
>                  ((`[min_heap_size ,v]) (/ v 2)))
>
> Admittedly, for the current pcase-lambda (and pcase-let) macro, the
> pcase.el code should be refined so as to emit a warning when it ends up
> ignoring a constant like `fullsweep_after' above.
>
>
Why not raise an error instead if there is no match (or even if any quoted
or self-quoting expressions are used at all)? The current behavior is quite
confusing, and warnings tend to be ignored.

Given that pcase-let, pcase-lambda and pcase-dolist don't do any
case-by-case analysis, maybe they should even be renamed and moved out of
pcase.el.
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 19:27:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Philipp Stephani <p.stephani2 <at> gmail.com>
Cc: Leo Liu <sdl.web <at> gmail.com>, 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 15:25:36 -0400
> Why not raise an error instead if there is no match

That would be an acceptable semantics, yes.  I happen to dislike it
because of the performance cost, where in most use-cases you know the
pattern will match and just want to replace a bunch of car/cdr/aref with
a single pattern.

I.e. the code you'd have written without pcase-let would have been

      (let ((a (foo))
            (b (car foo))
            (c (nth 2 foo)))

which would naturally turn into a pattern like `(,b ,_ ,c)
but if you want to signal an error when the pattern fails to match, then
you get 3 additional consp tests plus a null test, at which point the
performance impact can become noticeable.  You can get rid of the null
test with a pattern like `(,b ,_ ,c . ,_) but you can't get rid of the
3 consp tests.


        Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 20:33:02 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>, Philipp Stephani
 <p.stephani2 <at> gmail.com>
Cc: Leo Liu <sdl.web <at> gmail.com>, 20268 <at> debbugs.gnu.org
Subject: RE: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 8 Apr 2015 13:31:55 -0700 (PDT)
> I.e. the code you'd have written without pcase-let would have been
> 
>       (let ((a (foo))
>             (b (car foo))
>             (c (nth 2 foo)))
> 
> which would naturally turn into a pattern like `(,b ,_ ,c)

Just out of curiosity, what was the reason we didn't go in the
direction of Common Lisp's `destructuring-bind' etc., which would
let you write just (a b c) instead of `(,b ,_ ,c)?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 21:30:02 GMT) Full text and rfc822 format available.

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

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: Drew Adams <drew.adams <at> oracle.com>
Cc: Philipp Stephani <p.stephani2 <at> gmail.com>, Leo Liu <sdl.web <at> gmail.com>,
 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 08 Apr 2015 17:29:01 -0400
> Just out of curiosity, what was the reason we didn't go in the
> direction of Common Lisp's `destructuring-bind' etc., which would
> let you write just (a b c) instead of `(,b ,_ ,c)?

For example because it doesn't let you write

   (pcase-let ((cl-struct mytype slot1 slot3) (myexp))
     ...)


-- Stefan




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Wed, 08 Apr 2015 22:22:01 GMT) Full text and rfc822 format available.

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

From: Drew Adams <drew.adams <at> oracle.com>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Philipp Stephani <p.stephani2 <at> gmail.com>, Leo Liu <sdl.web <at> gmail.com>,
 20268 <at> debbugs.gnu.org
Subject: RE: bug#20268: 25.0.50; pcase-lambda broken
Date: Wed, 8 Apr 2015 15:21:10 -0700 (PDT)
> > Just out of curiosity, what was the reason we didn't go in the
> > direction of Common Lisp's `destructuring-bind' etc., which would
> > let you write just (a b c) instead of `(,b ,_ ,c)?
> 
> For example because it doesn't let you write
>    (pcase-let ((cl-struct mytype slot1 slot3) (myexp)) ...)

What part of "go in the direction of Common Lisp's
`destructuring-bind' etc." implies that you cannot go beyond it
to support that kind of thing?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#20268; Package emacs. (Tue, 08 Feb 2022 07:53:02 GMT) Full text and rfc822 format available.

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

From: Lars Ingebrigtsen <larsi <at> gnus.org>
To: Stefan Monnier <monnier <at> iro.umontreal.ca>
Cc: Leo Liu <sdl.web <at> gmail.com>, 20268 <at> debbugs.gnu.org
Subject: Re: bug#20268: 25.0.50; pcase-lambda broken
Date: Tue, 08 Feb 2022 08:52:05 +0100
Stefan Monnier <monnier <at> iro.umontreal.ca> writes:

>> After the recent rewrite, pcase-lambda is broken. For example, eval the
>> following to get 46422 instead of the correct value 65535.
>
>>    (cl-some (pcase-lambda (`[fullsweep_after ,v]) v)
>>             '([min_bin_vheap_size 46422]
>>               [min_heap_size 233]
>>               [fullsweep_after 65535]
>>               [minor_gcs 40]))
>
> Indeed, that's the semantics I chose.

So I think everything here works as designed, and I'm therefore closing
this bug report.

I see that pcase-lambda wasn't documented in the manual, so I've now
done so in Emacs 29.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no




bug marked as fixed in version 29.1, send any further explanations to 20268 <at> debbugs.gnu.org and Leo Liu <sdl.web <at> gmail.com> Request was from Lars Ingebrigtsen <larsi <at> gnus.org> to control <at> debbugs.gnu.org. (Tue, 08 Feb 2022 07:53:02 GMT) Full text and rfc822 format available.

bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Tue, 08 Mar 2022 12:24:13 GMT) Full text and rfc822 format available.

This bug report was last modified 2 years and 47 days ago.

Previous Next


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