Subject: bug#59887: closed (Re: bug#59887: pcase vs. pcase-let: Underscore in backquote-style patterns)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 12 Dec 2022 02:51:01 +0000

Your bug report

#59887: pcase vs. pcase-let: Underscore in backquote-style patterns

which was filed against the emacs package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
59887: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=59887
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#59887: pcase vs. pcase-let: Underscore in backquote-style patterns
From: Michael Heerdegen <[email-masked]>
To: hokomo <[email-masked]>
Cc: [email-masked]
Date: Mon, 12 Dec 2022 03:50:41 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

hokomo <[email-masked]> writes:

> How exactly is the underscore symbol treated in pcase's
> backquote-style patterns?

I think the current behavior can be understood and explained from the
documentation quite well.  If you can point to something concrete
missing, please elaborate, and we can reopen this report.

For now I'm closing it: everything works as documented, and we had
decided not to complicate the semantics of `_`, so as far as I see it
nothing is to be done here.

Thanks,

Michael.

Subject: pcase vs. pcase-let: Underscore in backquote-style patterns
From: hokomo <[email-masked]>
To: [email-masked]
Date: Wed, 07 Dec 2022 17:28:57 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hello,

How exactly is the underscore symbol treated in pcase's 
backquote-style patterns? Seems like at least pcase and pcase-let 
treat it inconsistently (I haven't checked the other pcase 
operators).

pcase treats the underscore as a literal symbol to match, hence 
this fails:

(pcase '(1 2 3)
  (`(1 _ ,x)
   x))

;; => nil

Adding the missing comma in front of the underscore gives us the 
expected behavior:

(pcase '(1 2 3)
  (`(1 ,_ ,x)
   x))

;; => 3

However, pcase-let is less strict about this, producing the same 
result with or without the comma:

(pcase-let ((`(1 _ ,x) '(1 2 3)))
  x)

;; => 3

(pcase-let ((`(1 ,_ ,x) '(1 2 3)))
  x)

;; => 3

Additionally, I would think one would still be able to match a 
literal underscore symbol even with pcase-let, but the following 
still ends up matching:

(pcase-let ((`(1 ,'_ ,x) '(1 2 3)))
  x)

;; => 3

I think that matching a literal underscore symbol is rare enough 
that the ideal behavior would probably be for an underscore within 
a backquote template to be treated as a wildcard whenever it 
appears literally (e.g., `(1 _)) or unquoted (e.g., `(1 ,_)). 
However, as soon as explicitly quoted (e.g., `(1 ,'_)), it should 
be treated as a match for a literal underscore symbol. In other 
words, I would expect the following would be different from the 
above:

(pcase '(1 2 3)
  (`(1 _ ,x)
   x))

;; => 3 (instead of nil)

(pcase-let ((`(1 ,'_ ,x) '(1 2 3)))
  x)

;; => nil (instead of 3)

I'm not 100% sure if these requirements would cause any 
backwards-incompatible changes or inconsistencies with the other 
pcase operators though. I'm also assuming that `(1 _) and `(1 ,'_) 
can be distinguished, but maybe this is not true?

hokomo