[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: The poor state of documentation of pcase like things.
From: |
Eli Zaretskii |
Subject: |
Re: The poor state of documentation of pcase like things. |
Date: |
Fri, 18 Dec 2015 10:55:21 +0200 |
> From: John Wiegley <address@hidden>
> Date: Thu, 17 Dec 2015 16:42:13 -0800
> Cc: Alan Mackenzie <address@hidden>, Emacs developers <address@hidden>
>
> >>>>> Kaushal Modi <address@hidden> writes:
>
> > I would welcome a short tutorial on how (and why) to use pcase.
>
> The following is a brief pcase tutorial. I welcome any edits and comments.
Thanks, please find below a few questions of a naïve reader.
> Also, I wonder if anyone would be willing to hammer this into a form better
> suited to the Emacs Lisp manual.
I could try, but only if I understand this enough to write about it,
and if the description you posted is complete (is it?). It's hard to
convert tutorials into a manual section otherwise.
> # QPatterns and UPatterns
>
> To master `pcase', there are two types of patterns you must know: UPatterns
> and QPatterns. UPatterns are the "logical" aspect of pattern matching, where
> we describe the kind of data we'd like to match against, and other special
> actions to take when it matches; and QPatterns are the "literal" aspect,
> stating the exact form of a particular match.
What do "Q" and "U" stand for? "Quoted" and "Unquoted", something
else? When introducing terminology that is not English words, you
need to help the reader form a mental model by connecting terms to
words.
> The only special QPattern is the anti-quoting pattern, `,foo`
But the example doesn't use `,foo`, it uses just ,foo. I guess `..`
here is some markdown-style "quoting", unrelated to the Lisp
backticks?
> (pcase value
> (`(1 2 ,(or `3 `4))
> (message "Matched either the list (1 2 3) or (1 2 4)")))
Do 3 and 4 really have to be quoted here? Why?
> When performing a match, if a symbol occurs within a UPattern, it binds
> whatever was found at that position to a local symbol of the same name.
"Local symbol" here meaning what? an un-interned symbol or a local
variable by that name?
> (pcase value
> (`(1 2 ,foo 3)
> (message "Matched 1, 2, something now bound to foo, and 3"))
> (foo
> (message "Match anything at all, and bind it to foo!"))
> (`(,the-car . ,the-cdr))
> (message "Match any cons cell, binding the car and cdr locally"))
So to bind something to 'foo' you just use "foo", but to bind
something to 'the-car' and 'the-cdr' you need to use ",the-car" and
",the-cdr"? Why the inconsistency?
> The reason for doing this is two-fold: Either to refer to a previous match
> later in the pattern (where it is compared using `eq'), or to make use of a
> matched value within the related code block:
>
> (pcase value
> (`(1 2 ,foo ,foo 3)
> (message "Matched (1 2 %s %s 3)" foo)))
??? Is "foo" here bound to 2 different values? And how come the
format has 2 %s, but only one variable, foo, to provide values?
> We can express boolean logic within a pattern match using the `or` and `and`
> Patterns:
>
> (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 did you use 'lambda' for the 3rd predicate, but not for the 2nd?
Is it just a way to show off use of 'lambda', or is there some
significant difference between these 2 use cases that requires a
'lambda' in the latter case? More generally, when is 'lambda'
required in a predicate like these ones?
> (pcase value
> (`(1 2 ,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"))))
How is using 'guard' here different from using a predicate?
> Note that in this example, the guard occurs at a match position, so even
> though the guard doesn't refer to what is being matched, if it passes, then
> whatever occurs at that position (the fourth element of the list), would be an
> unnamed successful matched.
What is the significance of an "unnamed successful matched"?
> This is rather bad form, so we can be more
> explicit about the logic here:
>
> (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"))))
>
>
> This means the same, but associates the guard with the value it tests, and
> makes it clear that we don't care what the fourth element is, only that it
> exists.
Again, how is this different from using a 'pred'?
>
> ## Pattern let bindings
>
> Within a pattern we can match sub-patterns, using a special form of let that
> has a meaning specific to `pcase':
>
> (pcase value
> (`(1 2 ,(and foo (let 3 foo)))
> (message "A weird way of matching (1 2 3)")))
>
> This example is a bit contrived, but it allows us to build up complex guard
> patterns that might match against values captured elsewhere in the surrounding
> code:
>
> (pcase value1
> (`(1 2 ,foo)
> (pcase value2
> (`(1 2 ,(and (let (or 3 4) foo) bar))
> (message "A nested pcase depends on the results of the first")))))
>
> Here the third value of `value2' -- which must be a list of exactly three
> elements, starting with 1 and 2 -- is being bound to the local variable `bar',
> but only if foo was a 3 or 4.
Why do you need the 'let' here? Binding bar to the 3rd element can be
expressed without a 'let', I think. And why is 'and' needed here?
> That's all there is to know about `pcase'! The other two utilities you might
> like to use are `pcase-let` and `pcase-let*`, which do similar things to their
> UPattern counter-part `let', but as regular Lisp forms:
>
> (pcase-let ((`(1 2 ,foo) value1)
> (`(3 4 ,bar) value2))
> (message "value1 is a list of (1 2 %s); value2 ends with %s"
> foo bar))
Isn't it true that pcase-let is just a short-hand for a pcase that
assigns values according to patterns, and has nil as the default
value? If that's true, I think it explains better what pcase-let
does, especially when backed up by an example of a pcase and the
equivalent pcase-let.
Looking at the ELisp manual's node "Pattern matching case statement",
it sounds like everything you've described is already covered there,
so perhaps what we need is more examples?
Thanks.
- Re: The poor state of documentation of pcase like things., (continued)
- Re: The poor state of documentation of pcase like things., Phillip Lord, 2015/12/19
- Re: The poor state of documentation of pcase like things., Richard Stallman, 2015/12/20
- RE: The poor state of documentation of pcase like things., Phillip Lord, 2015/12/20
- Re: The poor state of documentation of pcase like things., Richard Stallman, 2015/12/21
- Re: The poor state of documentation of pcase like things., Phillip Lord, 2015/12/21
- Re: The poor state of documentation of pcase like things., John Wiegley, 2015/12/22
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/20
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/20
- Re: The poor state of documentation of pcase like things., Phillip Lord, 2015/12/20
- Re: The poor state of documentation of pcase like things., Phillip Lord, 2015/12/19
- Re: The poor state of documentation of pcase like things.,
Eli Zaretskii <=
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/19
- Re: The poor state of documentation of pcase like things., John Wiegley, 2015/12/22
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/19
- Re: The poor state of documentation of pcase like things., Eli Zaretskii, 2015/12/19
- Re: The poor state of documentation of pcase like things., Eli Zaretskii, 2015/12/19
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/19
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/19
- Re: The poor state of documentation of pcase like things., John Wiegley, 2015/12/22
- Re: The poor state of documentation of pcase like things., Michael Heerdegen, 2015/12/19
- Re: The poor state of documentation of pcase like things., Eli Zaretskii, 2015/12/19