bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#70597: Problem in pcase-let?


From: Marco Antoniotti
Subject: bug#70597: Problem in pcase-let?
Date: Sun, 28 Apr 2024 00:28:41 +0200

Hi Bruno

Thank you for the reply, but sorry.  IMHO it is a bug,  At a minimum, because pcase and pcase-let behave differently.

I may be inclined to accept the explanation that the documentation about pcase-let allows for the behavior I find incorrect; that does not mean that the behavior is what is normally expected.

Pattern matchers do ... pattern matching.  If you allow quasiquotes or "incomplete specifications" (pick your preferred pattern matching terminology), then you should honor the expectations; hence two symbols that are not eq do not match.  Also note that I do not have any star (*) operators in my examples.

Again, the machinery is there, cfr, the example below, which selects the second clause.

ELISP> (pcase '(1 2 3 4)
           (`(1 2 ,x 5) (list 42 x))
           (`(1 ,x 3 4) (list 666 x)))
(666 2)

All the best

MA



On Sat, Apr 27, 2024 at 6:11 PM Bruno Barbier <brubar.cs@gmail.com> wrote:

Hi Marco,

I'm not a maintainer but let me try to explain; I'm sure someone will
correct me if I'm wrong.

In short: not a bug.

If I read your examples correctly, your problem could be reduced to this:
(using org mode syntax, I hope it's ok):

   #+begin_src elisp
     (pcase-let
         ((`(A *,c . ,r) '(A *1 2 3)))
       (list c r))
   #+end_src

   #+RESULTS:
   : (2 (3))


   #+begin_src elisp
     (pcase-let
         ((`(A *,c . ,r) '(B *1 2 3)))
       (list c r))
   #+end_src

   #+RESULTS:
   : (2 (3))

   #+begin_src elisp
     (pcase '(A *1 2 3)
       (`(B *,c . ,r) (list c r)))
   #+end_src

   #+RESULTS:
   : nil


The pcase-let documentation (describe-function 'pcase-let) says this:

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


Both of your pcase-let examples are actually undefined, because the
patterns don't match in *both* cases.  pcase-let works as documented:
it did bind some variables to arbitrary values.

That one matches (note the space between * and 1):
   #+begin_src elisp
     (pcase-let
         ((`(A * ,c . ,r) '(A * 1 2 3)))
       (list c r))
   #+end_src

   #+RESULTS:
   : (1 (2 3))

That one doesn't match either (replacing * with WORD), but same
result that your 2 pcase-let examples:
   #+begin_src elisp
     (pcase-let
         ((`(A *,c . ,r) '(A WORD1 2 3)))
       (list c r))
   #+end_src

   #+RESULTS:
   : (2 (3))


Note that *1 is one symbol whose name is "*1".  Your pattern `(*,c) is
looking for the symbol whose name is "*", followed by the value for c.

You may test your pattern, manually binding c to some value, to see
that you get a list containing 2 values:

   #+begin_src elisp
     (let ((c 1))
       `(*,c))
   #+end_src

   #+RESULTS:
   : (* 1)

Hoping this helps,

Bruno


--
Marco Antoniotti
Somewhere over the Rainbow

reply via email to

[Prev in Thread] Current Thread [Next in Thread]