[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Replace trivial pcase occurrences in the Emacs sources
From: |
Joost Kremers |
Subject: |
Re: Replace trivial pcase occurrences in the Emacs sources |
Date: |
Wed, 24 Oct 2018 10:34:23 +0200 |
User-agent: |
Mutt/1.9.4 (2018-02-28) |
On Wed, Oct 24, 2018 at 12:51:35AM -0400, Richard Stallman wrote:
> [[[ To any NSA and FBI agents reading my email: please consider ]]]
> [[[ whether defending the US Constitution against all enemies, ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> > In what sense is the above cl-case more clear than the pcase equivalent?
> > I'm not saying the pcase version is better in those cases, but I think
> > the respective advantages and disadvantages pretty much balance out.
>
> I also wonder. Is it simply that people find pcase unfamiliar?
Well, I can't speak for others, but personally, though I find pattern matching
as a concept straightforward and intuitive, pcase syntax seems unnecessarily
complex and unintuitive.
For example, John Wiegley's tutorial on pcase at
<http://newartisans.com/2016/01/pattern-matching-with-pcase/> has the following
example:
```
(pcase value
(`(,_ 1 2)
(message "Matched a list of anything followed by (1 2)")))
```
It is not clear to me why I couldn't simply write:
```
(pcase value
((_ 1 2)
(message "Matched a list of anything followed by (1 2)")))
```
I *can* understand the need to write:
```
(pcase value
(`(1 2 ,foo 3)
(message "Matched 1, 2, something now bound to foo, and 3")))
```
Instead of:
```
(pcase value
((1 2 foo 3)
(message "Matched 1, 2, something now bound to foo, and 3")))
```
This is obviously done in order to be able to match against the symbol `foo'
while at the same time be able to match anything and bind it to the symbol
`foo'. And even though this syntax with backquote and comma looks familiar to
anyone who's ever written a macro, their meaning is subtly different from their
meaning in macros. In pcase, «,foo» does *not* mean «evaluate `foo'», it means
something like «use `foo' as a variable».
So, while I understand the reasoning, it still makes me wonder why I can't
write something like this:
```
(pcase value
((1 2 % 3)
(message "Matched 1, 2, something now bound to %, and 3")))
```
That is, use a special symbol (I borrowed % from Clojure's anonymous functions)
to indicate that I want to match against any value and at the same time bind
that value. Obviously, the following:
```
(pcase value
((1 2 % %)
(message "Matched 1, 2, something now bound to %, and that same something
again")))
```
would then match lists of the form (1 2 3 3), not (1 2 3 4). If you need to
bind multiple values, I could imagine using something like:
```
(pcase value
((1 2 %1 %2)
(message "Matched 1, 2, something now bound to %1, and something (else)
bound to %2")))
```
Also, the use of `pred' and `guard' seem unnecessary. Instead of:
```
(pcase value
(`(1 2 ,(or 3 4)
,(and (pred stringp)
(pred (string> "aaa"))
(pred (lambda (x) (> (length x) 10)))))
(message "Matched 1, 2, 3 or 4, and a long string "
"that is lexically greater than 'aaa'")))
```
why not write:
```
(pcase value
((1 2 (or 3 4)
(and (stringp %)
(string> "aaa" %)
(> (length %) 10)))
(message "Matched 1, 2, 3 or 4, and a long string "
"that is lexically greater than 'aaa'")))
```
Similarly, the example:
```
(pcase value
(`(1 2 ,(and foo (guard (and (not (numberp foo)) (/= foo 10)))) _)
(message "Matched 1, 2, anything, and then anything again, "
"but only if the first anything wasn't the number 10"))))
```
uses `(and foo (guard ...))' to bind a value to `foo' and apply a predicate to
it. That's a coding pattern that you need to be familiar with in order to
understand what it does. (John explains it in his tutorial, but if I had met
this in the wild, I'd probably be puzzled by it at first). The % syntax would
seem to make this simpler as well:
```
(pcase value
((1 2 (and (not (numberp %)) (/= % 10)) _)
(message "Matched 1, 2, anything, and then anything again, "
"but only if the first anything wasn't the number 10"))))
```
This example also shows that `and' has a meaning in pcase that is subtly
different from its usual meaning in Lisp: `and' in a pcase 'UPattern' (as the
manual calls it) is not a logical `and' in the sense that it tests its
arguments for truthiness. Rather, it means «both arguments of `and' must apply
to the value at this position *regardless of truthiness*». (The `and' inside
the guard does have the usual meaning, of course.)
Mind you, I'm not arguing that pcase should be changed or replaced with
something that has this more intuitive (to me, anyway) syntax. I'm just trying
to explain why I personally find pcase difficult to wrap my head around, and
why I think this difficulty has to do with its syntax, which is different in
subtle ways, to such an extent that you can't, as an Elisp programmer tackling
pcase for the first time, just build on what you already know. You need to
actually bend your mind to incorporate the new stuff. Moreover, at first sight,
there doesn't seem to be much of an advantage to this syntax, since an
alternative syntax that doesn't have the same disadvantage seems feasible.
I say "seems", because it's entirely possible that this particular syntax has
capabilities that wouldn't be possible with a simpler syntax. But for a pcase
newbie, that's not immediately obvious. The only reason that I can think of why
the %-syntax or something similar isn't used is that it's dangerous in an
environment that doesn't have lexical scope...
Just my two cents, of course.
--
Joost Kremers
Life has its moments
- Re: Replace trivial pcase occurrences in the Emacs sources, (continued)
- Re: Replace trivial pcase occurrences in the Emacs sources, Alan Mackenzie, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Stephen Berman, 2018/10/25
- Re: Replace trivial pcase occurrences in the Emacs sources, Eli Zaretskii, 2018/10/25
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/25
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/26
- Re: Replace trivial pcase occurrences in the Emacs sources, Garreau\, Alexandre, 2018/10/27
- Re: Replace trivial pcase occurrences in the Emacs sources, Richard Stallman, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources,
Joost Kremers <=
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Daniel Pittman, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/24
- pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources), Stefan Monnier, 2018/10/24
- Re: pcase pattern syntax (was: Replace trivial pcase occurrences in the Emacs sources), Joost Kremers, 2018/10/26
- Re: Replace trivial pcase occurrences in the Emacs sources, João Távora, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Richard Stallman, 2018/10/24
- Re: Replace trivial pcase occurrences in the Emacs sources, Stefan Monnier, 2018/10/25
- Re: Replace trivial pcase occurrences in the Emacs sources, Andy Moreton, 2018/10/25