* Re: Update of pcase docs for the elisp manual
[not found] ` <m2powt5w50.fsf@newartisans.com>
@ 2016-01-23 11:17 ` Eli Zaretskii
2016-01-24 4:40 ` Stefan Monnier
` (2 more replies)
0 siblings, 3 replies; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-23 11:17 UTC (permalink / raw
To: John Wiegley, Michael Heerdegen; +Cc: emacs-devel
> From: John Wiegley <jwiegley@gmail.com>
> Cc: Eli Zaretskii <eliz@gnu.org>
> Date: Fri, 22 Jan 2016 10:03:55 -0800
>
> Below is an update to the pcase.texi I sent earlier, with Michael's
> corrections.
Thanks.
> Eli, I'm not sure the Texinfo here is even sane.
Texinfo is the least of our problems in this and similar cases.
I updated the docs, thanks to both of you. I used your text, John,
and also Michael's pcase-guide.el as the starting points, source of
inspiration and examples, and sometimes source of swaths of text as
well. I also used what was already in the manual. The end result,
for which I accept full responsibility (although you are named as
co-authors), is in the repository; please take a look and comment,
modify, and improve as appropriate. In particular, the UPattern
example needs to be improved as the comment there says, please do so
if you have time.
Some subtle points that I still don't regard as resolved in a
satisfactory manner:
. The description of the 'let' pattern is not entirely clear.
Michael's examples actually confused me instead of helping to
understand it, because the examples use the same symbol for the
1st arg of 'pcase' and for symbols that are UPatterns (and also in
other contexts). Example:
(pcase x
((and (pred numberp)
(let (pred (lambda (x) (< 5 x)))
(abs x)))
t)
(_ nil))
The documentation of 'let' says that it matches if the expression
matches the pattern. Here, the expression is "(abs x)" and the
pattern is "(pred (lambda (x) (< 5 x)))", right? So how can they
"match"? The fact that 'x' is used here in no less than 3
different contexts doesn't help, either. I actually don't
understand the "(abs x)" part at all, since 'x' was not bound to
anything by any previous pattern. AFAIU, the 1st argument of
'pcase' cannot be used like that, because it will not be a symbol
in the general case, it's an expression whose value is not bound
to anything.
The sharp-eyed among you might notice that the documentation of
the 'let' pattern is somewhat vague -- the above is the reason.
. The exact syntax and possible forms of QPatterns are described
ambiguously and seemingly incompletely, and profoundly contradict
almost every given example of them. Both Michael and the previous
manual text describe them as follows:
The form is `QPAT where QPAT is one of the following:
(QPAT1 . QPAT2)
[QPAT1 QPAT2 ... QPATn]
,PAT
ATOM
The last two look wrong: AFAIU, there is no QPattern of the form
`,PATH or `ATOM. These 2 seem to be _components_ or QPatterns,
see below.
The examples are terribly confusing. They all use this form:
`(A B C D ...)
where each of A, B, etc. can be one of:
- ,UPAT
- ATOM
And yet this pattern doesn't appear at all in the possible forms
of QPAT above!
. Many of the examples using QPatterns seem to allow to be easily
rewritten to use only UPatterns, by adding additional 'pred' and
'guard' conditions. Is that true? If so, we should tell this
somewhere, because otherwise the reader might think she
misunderstood something very important. I did, because none of
the texts I've seen in preparation for this work discusses this
aspect. Take this, for example:
(pcase x
(`("foo") t)
(`("foo" ,a) a)
(`("foo" . ,(and (pred listp) rest)) rest))
What do we have here that cannot be done with UPatterns?
. Last, but not least: NEWS says we now have a new UPattern 'quote',
but neither John, nor Michael or the doc strings mention this
pattern. What did I miss?
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-23 11:17 ` Update of pcase docs for the elisp manual Eli Zaretskii
@ 2016-01-24 4:40 ` Stefan Monnier
2016-01-24 14:33 ` Eli Zaretskii
2016-01-25 14:15 ` Michael Heerdegen
2016-01-26 16:59 ` John Wiegley
2 siblings, 1 reply; 28+ messages in thread
From: Stefan Monnier @ 2016-01-24 4:40 UTC (permalink / raw
To: emacs-devel
> (pcase x
> ((and (pred numberp)
> (let (pred (lambda (x) (< 5 x)))
> (abs x)))
The second arg to `let' (i.e. (abs x) here) is a plain old normal
expression, so it does not necessarily use the currently matched object
and if it wants to, it can do it as above by simply re-using the same
expression as was passed to `pcase'.
Then the result of this expression is matched against the first arg of
`let' (i.e. (pred (lambda (x) (< 5 x))) here).
So (let (pred (lambda (x) (< 5 x))) (abs x)) ends up being equivalent to
(guard (< 5 (abs x))).
> . The exact syntax and possible forms of QPatterns are described
> ambiguously and seemingly incompletely, and profoundly contradict
> almost every given example of them. Both Michael and the previous
> manual text describe them as follows:
> The form is `QPAT where QPAT is one of the following:
> (QPAT1 . QPAT2)
> [QPAT1 QPAT2 ... QPATn]
> ,PAT
> ATOM
> The last two look wrong: AFAIU, there is no QPattern of the form
> `,PATH
I think `,PAT is a valid UPattern, which is simply equivalent to PAT.
> or `ATOM.
And `ATOM is also a valid UPattern.
> The examples are terribly confusing. They all use this form:
> `(A B C D ...)
> where each of A, B, etc. can be one of:
> - ,UPAT
> - ATOM
> And yet this pattern doesn't appear at all in the possible forms
> of QPAT above!
Of course it does: `(A B C D ...) is 100% equivalent to
`(A . (B . (C . (D . ...)))) and (QPAT1 . QPAT2) is a QPAT.
> . Many of the examples using QPatterns seem to allow to be easily
> rewritten to use only UPatterns, by adding additional 'pred' and
> 'guard' conditions. Is that true?
Very much so. QPatterns aren't "core patterns". So much so that in
Emacs-25 the `QPAT form is actually defined on top of the core patterns
using pcase-defmacro.
> . Last, but not least: NEWS says we now have a new UPattern 'quote',
> but neither John, nor Michael or the doc strings mention this
> pattern. What did I miss?
The docstring says:
'VAL matches if the object is ‘equal’ to VAL.
and 'VAL is also spelled (quote VAL).
Stefan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-24 4:40 ` Stefan Monnier
@ 2016-01-24 14:33 ` Eli Zaretskii
2016-01-24 23:17 ` Stefan Monnier
2016-01-25 14:22 ` Michael Heerdegen
0 siblings, 2 replies; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-24 14:33 UTC (permalink / raw
To: Stefan Monnier, Michael Heerdegen; +Cc: emacs-devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Sat, 23 Jan 2016 23:40:19 -0500
>
> > (pcase x
> > ((and (pred numberp)
> > (let (pred (lambda (x) (< 5 x)))
> > (abs x)))
>
> The second arg to `let' (i.e. (abs x) here) is a plain old normal
> expression, so it does not necessarily use the currently matched object
> and if it wants to, it can do it as above by simply re-using the same
> expression as was passed to `pcase'.
Yes, I know. That's not the confusing part (although re-using 'x' in
this way muddies the waters and doesn't help).
> So (let (pred (lambda (x) (< 5 x))) (abs x)) ends up being equivalent to
> (guard (< 5 (abs x))).
Yes, because it doesn't use the feature for which 'let' was invented:
it doesn't bind any symbols to values. And that's the confusing part:
'let' is being used where it isn't really needed, so this is not the
ideal example for the 'let' pattern.
> > . The exact syntax and possible forms of QPatterns are described
> > ambiguously and seemingly incompletely, and profoundly contradict
> > almost every given example of them. Both Michael and the previous
> > manual text describe them as follows:
> >
> > The form is `QPAT where QPAT is one of the following:
> >
> > (QPAT1 . QPAT2)
> > [QPAT1 QPAT2 ... QPATn]
> > ,PAT
> > ATOM
> >
> > The last two look wrong: AFAIU, there is no QPattern of the form
> > `,PATH
>
> I think `,PAT is a valid UPattern, which is simply equivalent to PAT.
>
> > or `ATOM.
>
> And `ATOM is also a valid UPattern.
The above describes QPatterns, not UPatterns. I also arrived at the
conclusion that we should talk about UPatterns (see how I changed the
above for the manual), but then those 2 shouldn't appear in the list
as QPatterns, they should be explained as UPatterns a QPattern can use
by unquoting them. Which is exactly what I did in the manual.
> > The examples are terribly confusing. They all use this form:
> > `(A B C D ...)
> > where each of A, B, etc. can be one of:
> > - ,UPAT
> > - ATOM
> > And yet this pattern doesn't appear at all in the possible forms
> > of QPAT above!
>
> Of course it does: `(A B C D ...) is 100% equivalent to
> `(A . (B . (C . (D . ...)))) and (QPAT1 . QPAT2) is a QPAT.
Which IMO means we must add the likes of `(A B C D) to the manual,
because expecting the readers of software documentation to solve
riddles as they read is not a good idea.
> > . Many of the examples using QPatterns seem to allow to be easily
> > rewritten to use only UPatterns, by adding additional 'pred' and
> > 'guard' conditions. Is that true?
>
> Very much so.
Then this, too, should be added, probably with an example. Michael,
would you mind providing an educational example for that, please?
> > . Last, but not least: NEWS says we now have a new UPattern 'quote',
> > but neither John, nor Michael or the doc strings mention this
> > pattern. What did I miss?
>
> The docstring says:
>
> 'VAL matches if the object is ‘equal’ to VAL.
>
> and 'VAL is also spelled (quote VAL).
This probably means that 'quote' shouldn't be documented as a separate
pattern, as that is a technicality which is much more likely to
confuse than to help understanding. Unless, that is, there are
important scenarios where using (quote FOO) in a pattern is required
where it isn't a trivial replacement for 'FOO. Do you know about such
scenarios?
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-24 14:33 ` Eli Zaretskii
@ 2016-01-24 23:17 ` Stefan Monnier
2016-01-25 16:14 ` Eli Zaretskii
2016-01-25 14:22 ` Michael Heerdegen
1 sibling, 1 reply; 28+ messages in thread
From: Stefan Monnier @ 2016-01-24 23:17 UTC (permalink / raw
To: emacs-devel
>> So (let (pred (lambda (x) (< 5 x))) (abs x)) ends up being equivalent to
>> (guard (< 5 (abs x))).
> Yes, because it doesn't use the feature for which 'let' was invented:
> it doesn't bind any symbols to values. And that's the confusing part:
> 'let' is being used where it isn't really needed, so this is not the
> ideal example for the 'let' pattern.
Agreed.
>> > . The exact syntax and possible forms of QPatterns are described
>> > ambiguously and seemingly incompletely, and profoundly contradict
>> > almost every given example of them. Both Michael and the previous
>> > manual text describe them as follows:
>> >
>> > The form is `QPAT where QPAT is one of the following:
>> >
>> > (QPAT1 . QPAT2)
>> > [QPAT1 QPAT2 ... QPATn]
>> > ,PAT
>> > ATOM
>> >
>> > The last two look wrong: AFAIU, there is no QPattern of the form
>> > `,PATH
>>
>> I think `,PAT is a valid UPattern, which is simply equivalent to PAT.
>>
>> > or `ATOM.
>>
>> And `ATOM is also a valid UPattern.
> The above describes QPatterns, not UPatterns.
Yes, the ` pcase-macro introduces a new kind of patterns (the
QPatterns) which are those that appear under the ` .
So when I say that `ATOM is a valid UPattern, it means that ATOM is
a valid QPattern. And similarly when I say that "`,PAT is a valid
UPattern" it means that ",PAT" is a valid QPattern.
The QPattern and UPattern languages are not mutually exclusive: you
can't tell by looking at a pattern if it's a QPattern or a UPattern.
Instead, the context (whether it's within a ` or not) determines which
of the two is expected.
>> Of course it does: `(A B C D ...) is 100% equivalent to
>> `(A . (B . (C . (D . ...)))) and (QPAT1 . QPAT2) is a QPAT.
> Which IMO means we must add the likes of `(A B C D) to the manual,
> because expecting the readers of software documentation to solve
> riddles as they read is not a good idea.
Agreed. Not needed for the docstring (which is more meant as
a reference for people who already know how it works, and needs to be
both exhaustive and concise), but useful for the manual.
>> > . Last, but not least: NEWS says we now have a new UPattern 'quote',
>> > but neither John, nor Michael or the doc strings mention this
>> > pattern. What did I miss?
>> The docstring says:
>> 'VAL matches if the object is ‘equal’ to VAL.
>> and 'VAL is also spelled (quote VAL).
> This probably means that 'quote' shouldn't be documented as a separate
> pattern, as that is a technicality which is much more likely to
> confuse than to help understanding.
Just like the (A B C) vs (A . (B . (C . nil))) issue, 'A is one and the
same as (quote A), so it's definitely not a separate pattern. The NEWS
file used the term "quote" because I find it clearer to talk about "the
`quote' pattern" than "the ' pattern".
> Unless, that is, there are important scenarios where using (quote FOO)
> in a pattern is required where it isn't a trivial replacement
> for 'FOO.
A macro (such as pcase) can never distinguish 'A from (quote A) since
the reader returns exactly the same result either way.
Stefan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-23 11:17 ` Update of pcase docs for the elisp manual Eli Zaretskii
2016-01-24 4:40 ` Stefan Monnier
@ 2016-01-25 14:15 ` Michael Heerdegen
2016-01-25 16:33 ` Eli Zaretskii
2016-01-26 16:59 ` John Wiegley
2 siblings, 1 reply; 28+ messages in thread
From: Michael Heerdegen @ 2016-01-25 14:15 UTC (permalink / raw
To: Eli Zaretskii; +Cc: John Wiegley, emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> . The description of the 'let' pattern is not entirely clear.
> Michael's examples actually confused me instead of helping to
> understand it, because the examples use the same symbol for the
> 1st arg of 'pcase' and for symbols that are UPatterns (and also in
> other contexts). Example:
>
> (pcase x
> ((and (pred numberp)
> (let (pred (lambda (x) (< 5 x)))
> (abs x)))
> t)
> (_ nil))
>
> The documentation of 'let' says that it matches if the expression
> matches the pattern. Here, the expression is "(abs x)" and the
> pattern is "(pred (lambda (x) (< 5 x)))", right?
Yes.
> So how can they "match"? The fact that 'x' is used here in no
> less than 3 different contexts doesn't help, either. I actually
> don't understand the "(abs x)" part at all, since 'x' was not
> bound to anything by any previous pattern. AFAIU, the 1st
> argument of 'pcase' cannot be used like that, because it will not
> be a symbol in the general case, it's an expression whose value is
> not bound to anything.
That's all correct. Though, if we test the value of the variable `x'
with pcase, this makes only sense if `x' is bound. And we made a
`numberp' test quite before, so the expression (abs x) makes sense, and
is "in the same context as `x' tested expression.
That the lambda in the `pred' uses x as a new global variable is bad
indeed, we should use a different name.
Dunno if it's a good example at all. But since just binding a symbol is
better done with just SYMBOL as pattern, I wanted to provide an example
that shows a different use case.
> The sharp-eyed among you might notice that the documentation of
> the 'let' pattern is somewhat vague -- the above is the reason.
Sorry, I've lost my orientation. What is the reason?
> . The exact syntax and possible forms of QPatterns are described
> ambiguously and seemingly incompletely, and profoundly contradict
> almost every given example of them. Both Michael and the previous
> manual text describe them as follows:
>
> The form is `QPAT where QPAT is one of the following:
>
> (QPAT1 . QPAT2)
> [QPAT1 QPAT2 ... QPATn]
> ,PAT
> ATOM
>
> The last two look wrong: AFAIU, there is no QPattern of the form
> `,PATH or `ATOM. These 2 seem to be _components_ or QPatterns,
> see below.
Did Stefan make it clear for you?
> . Many of the examples using QPatterns seem to allow to be easily
> rewritten to use only UPatterns, by adding additional 'pred' and
> 'guard' conditions. Is that true? If so, we should tell this
> somewhere, because otherwise the reader might think she
> misunderstood something very important. I did, because none of
> the texts I've seen in preparation for this work discusses this
> aspect. Take this, for example:
>
> (pcase x
> (`("foo") t)
> (`("foo" ,a) a)
> (`("foo" . ,(and (pred listp) rest)) rest))
>
> What do we have here that cannot be done with UPatterns?
How would you rewrite
`("foo" . ,(and (pred listp) rest))
using only Upatterns? The shortest way would probably look like this:
(and (pred consp)
(app car "foo")
(app cdr (and (pred listp) rest)))
Everything involving QPatterns can be expressed without them. So I'm
not sure what you mean.
Thanks,
Michael.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-24 14:33 ` Eli Zaretskii
2016-01-24 23:17 ` Stefan Monnier
@ 2016-01-25 14:22 ` Michael Heerdegen
1 sibling, 0 replies; 28+ messages in thread
From: Michael Heerdegen @ 2016-01-25 14:22 UTC (permalink / raw
To: emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> > and 'VAL is also spelled (quote VAL).
>
> This probably means that 'quote' shouldn't be documented as a separate
> pattern, as that is a technicality which is much more likely to
> confuse than to help understanding. Unless, that is, there are
> important scenarios where using (quote FOO) in a pattern is required
> where it isn't a trivial replacement for 'FOO. Do you know about such
> scenarios?
It should not do harm if you avoid to spell out 'FOO as (quote FOO) in
any docs, I think.
Michael.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-24 23:17 ` Stefan Monnier
@ 2016-01-25 16:14 ` Eli Zaretskii
2016-01-26 1:40 ` Stefan Monnier
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-25 16:14 UTC (permalink / raw
To: Stefan Monnier; +Cc: emacs-devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Date: Sun, 24 Jan 2016 18:17:10 -0500
>
> >> > . The exact syntax and possible forms of QPatterns are described
> >> > ambiguously and seemingly incompletely, and profoundly contradict
> >> > almost every given example of them. Both Michael and the previous
> >> > manual text describe them as follows:
> >> >
> >> > The form is `QPAT where QPAT is one of the following:
> >> >
> >> > (QPAT1 . QPAT2)
> >> > [QPAT1 QPAT2 ... QPATn]
> >> > ,PAT
> >> > ATOM
> >> >
> >> > The last two look wrong: AFAIU, there is no QPattern of the form
> >> > `,PATH
> >>
> >> I think `,PAT is a valid UPattern, which is simply equivalent to PAT.
> >>
> >> > or `ATOM.
> >>
> >> And `ATOM is also a valid UPattern.
> > The above describes QPatterns, not UPatterns.
>
> Yes, the ` pcase-macro introduces a new kind of patterns (the
> QPatterns) which are those that appear under the ` .
>
> So when I say that `ATOM is a valid UPattern, it means that ATOM is
> a valid QPattern. And similarly when I say that "`,PAT is a valid
> UPattern" it means that ",PAT" is a valid QPattern.
What I wrote in the manual uses the reverse notation: QPatterns
_include_ the backquote. The reason for adopting this notation was
that every time QPatterns are used, the backquote is there. So IMO
the description makes more sense the way I wrote it.
> The QPattern and UPattern languages are not mutually exclusive: you
> can't tell by looking at a pattern if it's a QPattern or a UPattern.
> Instead, the context (whether it's within a ` or not) determines which
> of the two is expected.
That's not an important distinction for using the languages, IMO. I
understand how it can be important for someone who knows the
implementation very well.
> >> Of course it does: `(A B C D ...) is 100% equivalent to
> >> `(A . (B . (C . (D . ...)))) and (QPAT1 . QPAT2) is a QPAT.
> > Which IMO means we must add the likes of `(A B C D) to the manual,
> > because expecting the readers of software documentation to solve
> > riddles as they read is not a good idea.
>
> Agreed. Not needed for the docstring (which is more meant as
> a reference for people who already know how it works, and needs to be
> both exhaustive and concise), but useful for the manual.
My quotation was not from the doc string, but from Michael's tutorial.
> >> > . Last, but not least: NEWS says we now have a new UPattern 'quote',
> >> > but neither John, nor Michael or the doc strings mention this
> >> > pattern. What did I miss?
> >> The docstring says:
> >> 'VAL matches if the object is ‘equal’ to VAL.
> >> and 'VAL is also spelled (quote VAL).
> > This probably means that 'quote' shouldn't be documented as a separate
> > pattern, as that is a technicality which is much more likely to
> > confuse than to help understanding.
>
> Just like the (A B C) vs (A . (B . (C . nil))) issue, 'A is one and the
> same as (quote A), so it's definitely not a separate pattern.
We can certainly point out the difference between A and 'A in this
context, but I see no reason to document 'quote' as a separate pattern.
> > Unless, that is, there are important scenarios where using (quote FOO)
> > in a pattern is required where it isn't a trivial replacement
> > for 'FOO.
>
> A macro (such as pcase) can never distinguish 'A from (quote A) since
> the reader returns exactly the same result either way.
Sorry, is that a no?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-25 14:15 ` Michael Heerdegen
@ 2016-01-25 16:33 ` Eli Zaretskii
2016-01-28 18:37 ` Michael Heerdegen
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-25 16:33 UTC (permalink / raw
To: Michael Heerdegen; +Cc: johnw, emacs-devel
> From: Michael Heerdegen <michael_heerdegen@web.de>
> Cc: John Wiegley <johnw@gnu.org>, emacs-devel@gnu.org
> Date: Mon, 25 Jan 2016 15:15:14 +0100
>
> Dunno if it's a good example at all. But since just binding a symbol is
> better done with just SYMBOL as pattern, I wanted to provide an example
> that shows a different use case.
I understand. I'm just saying that it would be better to provide an
example of using 'let' which actually made use of the reason for its
introduction: binding symbols to values.
>
> > The sharp-eyed among you might notice that the documentation of
> > the 'let' pattern is somewhat vague -- the above is the reason.
>
> Sorry, I've lost my orientation. What is the reason?
My confusion when I tried to take apart the 'let' example.
> > . The exact syntax and possible forms of QPatterns are described
> > ambiguously and seemingly incompletely, and profoundly contradict
> > almost every given example of them. Both Michael and the previous
> > manual text describe them as follows:
> >
> > The form is `QPAT where QPAT is one of the following:
> >
> > (QPAT1 . QPAT2)
> > [QPAT1 QPAT2 ... QPATn]
> > ,PAT
> > ATOM
> >
> > The last two look wrong: AFAIU, there is no QPattern of the form
> > `,PATH or `ATOM. These 2 seem to be _components_ or QPatterns,
> > see below.
>
> Did Stefan make it clear for you?
Like I said: he made it clear that you use a different "language"
here, the opposite of what I used.
> Everything involving QPatterns can be expressed without them. So I'm
> not sure what you mean.
I only talked about the examples I've seen, and I said explicitly "can
be _easily_ rewritten to use only UPatterns". The "easily" part is
important. IOW, when we show examples of QPatterns that can be too
easily rewritten without QPatterns, we should at least say in a side
note that this is possible, that we nevertheless provide such examples
just for brevity, and perhaps try avoiding such _easily_ rewritable
examples altogether. IME, text that begs some question should answer
that question right there and then, otherwise the reader is left with
an impression that she didn't fully understand something important.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-25 16:14 ` Eli Zaretskii
@ 2016-01-26 1:40 ` Stefan Monnier
2016-01-26 15:38 ` Eli Zaretskii
0 siblings, 1 reply; 28+ messages in thread
From: Stefan Monnier @ 2016-01-26 1:40 UTC (permalink / raw
To: Eli Zaretskii; +Cc: emacs-devel
> What I wrote in the manual uses the reverse notation: QPatterns
> _include_ the backquote.
Then these are UPatterns (the subset of them that is prefixed with `).
And then you can use the notion of "QPattern" to describe what can
appear *inside* a backquoted pattern.
E.g. you say "QPatterns can have one of the following forms:" and then
list some examples but this list is not exhaustive since it doesn't
include cases such as:
`(foo ,bar baz)
or
`(foo (bar ,baz) (,titi toto))
Additionally, you say
`(@var{qpattern1} . @var{qpattern2})
is a valid qpattern, which could lead people to try and use things like
`(`(a . b) . `(c . d))
which are not invalid but probably don't do what was intended
(this will test
(equal x '(`(a . b) . `(c . d)))
rather than
(equal x '((a . b) . (c . d)))
)
Also it says that @var{atom} and ,@var{upattern} are "qpatterns", which
would literally mean that you can write
(pcase foo
(,toto blabla))
which is not valid.
I've appended a suggested patch to try and correct those inaccuracies.
I'm afraid the result is too "dry" (too hard to understand), tho.
>> Agreed. Not needed for the docstring (which is more meant as
>> a reference for people who already know how it works, and needs to be
>> both exhaustive and concise), but useful for the manual.
> My quotation was not from the doc string, but from Michael's tutorial.
Ah, that explains why you used "UPattern" (I used this in the Emacs-24
version of pcase where the ` pattern was hardcoded, but in the Emacs-25
code I've switched to using just Pattern instead).
>> > Unless, that is, there are important scenarios where using (quote FOO)
>> > in a pattern is required where it isn't a trivial replacement
>> > for 'FOO.
>> A macro (such as pcase) can never distinguish 'A from (quote A) since
>> the reader returns exactly the same result either way.
> Sorry, is that a no?
It's not just a "no", it's a "no, because it's impossible".
I thought that would be obvious to a seasoned Lisper like you, but
clearly it isn't so we need to say it more explicitly.
Stefan
diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 6fa802d..cf65d3e 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -319,16 +319,11 @@ Pattern matching case statement
and returns the value of the last of @var{body-forms}. Any remaining
@var{clauses} are ignored.
-The @var{pattern} part of a clause can be of one of two types:
-@dfn{QPattern}, a pattern quoted with a backquote; or a
-@dfn{UPattern}, which is not quoted. UPatterns are simpler, so we
-describe them first.
-
Note: In the description of the patterns below, we use ``the value
being matched'' to refer to the value of the @var{expression} that is
the first argument of @code{pcase}.
-A UPattern can have one of the following forms:
+A UPattern can have the following forms:
@table @code
@@ -407,24 +402,29 @@ Pattern matching case statement
(code (message "Unknown return code %S" code)))
@end example
-The QPatterns are more powerful. They allow matching the value of the
-@var{expression} that is the first argument of @code{pcase} against
-specifications of its @emph{structure}. For example, you can specify
-that the value must be a list of 2 elements whose first element is a
-string and the second element is a number. QPatterns can have one of
-the following forms:
+@node Pcase with backquotes
+@subsubsection Pcase with backquotes
+
+Additionally to the above patterns, one can also use a backquoted
+pattern. This facility is designed with the idea that a backquoted
+pattern should match all values that could be constructed
+by a similarly backquoted expression. For example, you can specify
+that the value must be a list of 2 elements whose first element is the
+string @code{"first"} with a pattern like @code{`("first" ,elem)}.
+
+Backquoted patterns are written @code{`@var{qpattern}} where
+@var{qpattern} can have the following forms:
@table @code
-@item `(@var{qpattern1} . @var{qpattern2})
+@item (@var{qpattern1} . @var{qpattern2})
Matches if the value being matched is a cons cell whose @code{car}
matches @var{qpattern1} and whose @code{cdr} matches @var{qpattern2}.
-@item `[@var{qpattern1} @var{qpattern2} @dots{} @var{qpatternm}]
+This generalizes to (@var{qpattern1} @var{qpattern2} @dots{}
+@var{qpatternn}), of course.
+@item [@var{qpattern1} @var{qpattern2} @dots{} @var{qpatternm}]
Matches if the value being matched is a vector of length @var{m} whose
@code{0}..@code{(@var{m}-1)}th elements match @var{qpattern1},
@var{qpattern2} @dots{} @var{qpatternm}, respectively.
-@item `(,@var{upattern1} ,@var{upattern2} @dots{})
-Matches if the value being matched is a list whose elements match the
-corresponding @var{upattern1}, @var{upattern2}, etc.
@item @var{atom}
Matches if corresponding element of the value being matched is
@code{equal} to the specified @var{atom}.
@@ -435,6 +435,9 @@ Pattern matching case statement
@end defmac
+@node Pcase example
+@subsubsection Pcase example
+
Here is an example of using @code{pcase} to implement a simple
interpreter for a little expression language (note that this example
requires lexical binding, @pxref{Lexical Binding}):
@@ -472,12 +475,20 @@ Pattern matching case statement
(evaluate '(sub 1 2) nil) ;=> error
@end example
+@node Pcase macros
+@subsubsection Pcase macros
+
Additional UPatterns can be defined using the @code{pcase-defmacro}
macro.
@defmac pcase-defmacro name args &rest body
-Define a new UPattern for @code{pcase}. The UPattern will have the
-form @code{(@var{name} @var{args})}.
+Define a new kind of UPattern for @code{pcase} by describing how to
+rewrite it into some other UPattern.
+
+More specifically, this definition states that any UPattern of the
+form @code{(@var{name} @var{actual-args})} will be rewritten into the
+UPattern obtained by evaluating @var{body} in an environment where
+@var{args} are bound to @var{actual-args}.
@end defmac
@node Combining Conditions
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 1:40 ` Stefan Monnier
@ 2016-01-26 15:38 ` Eli Zaretskii
2016-01-26 16:23 ` Stefan Monnier
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-26 15:38 UTC (permalink / raw
To: Stefan Monnier; +Cc: emacs-devel
> From: Stefan Monnier <monnier@iro.umontreal.ca>
> Cc: emacs-devel@gnu.org
> Date: Mon, 25 Jan 2016 20:40:12 -0500
>
> >> > Unless, that is, there are important scenarios where using (quote FOO)
> >> > in a pattern is required where it isn't a trivial replacement
> >> > for 'FOO.
> >> A macro (such as pcase) can never distinguish 'A from (quote A) since
> >> the reader returns exactly the same result either way.
> > Sorry, is that a no?
>
> It's not just a "no", it's a "no, because it's impossible".
> I thought that would be obvious to a seasoned Lisper like you, but
> clearly it isn't so we need to say it more explicitly.
pcase isn't Lisp, it's a macro that assigns different meanings to some
Lisp constructs.
> I've appended a suggested patch to try and correct those inaccuracies.
Thanks. But I don't understand the rationale for most of the
changes. I understand why you suggest to use "backquoted patterns"
where I used "QPatterns", and I agree with that. But why all the
other changes? E.g., this:
> -The @var{pattern} part of a clause can be of one of two types:
> -@dfn{QPattern}, a pattern quoted with a backquote; or a
> -@dfn{UPattern}, which is not quoted. UPatterns are simpler, so we
> -describe them first.
If we use "backquoted patterns" here, the rest does have a purpose,
and removing it diminishes the ease of reading, I think. The purpose
of this was to provide some outlook on the issue that's about to be
described.
> -The QPatterns are more powerful. They allow matching the value of the
> -@var{expression} that is the first argument of @code{pcase} against
> -specifications of its @emph{structure}. For example, you can specify
> -that the value must be a list of 2 elements whose first element is a
> -string and the second element is a number. QPatterns can have one of
> -the following forms:
> +@node Pcase with backquotes
> +@subsubsection Pcase with backquotes
> +
> +Additionally to the above patterns, one can also use a backquoted
> +pattern. This facility is designed with the idea that a backquoted
> +pattern should match all values that could be constructed
> +by a similarly backquoted expression. For example, you can specify
> +that the value must be a list of 2 elements whose first element is the
> +string @code{"first"} with a pattern like @code{`("first" ,elem)}.
I agree that your example is better, but why the other changes? Why
is it important to tell the reader the design idea?
I also don't think further dividing this sub-section into
sub-sub-sections is a good idea: there are less than 200 lines in it,
so it's not too large. The last sub-sub-section you holds just 6
lines, way to few to justify a separate unit, I think.
In general, subdividing into nodes breaks the continuity of
description, so it's only justified for significant portions or for
some obscure aspect (like an extended footnote), or for almost
entirely unrelated subjects. None of that happens here, I think.
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 15:38 ` Eli Zaretskii
@ 2016-01-26 16:23 ` Stefan Monnier
0 siblings, 0 replies; 28+ messages in thread
From: Stefan Monnier @ 2016-01-26 16:23 UTC (permalink / raw
To: emacs-devel
>> >> > Unless, that is, there are important scenarios where using (quote FOO)
>> >> > in a pattern is required where it isn't a trivial replacement
>> >> > for 'FOO.
>> >> A macro (such as pcase) can never distinguish 'A from (quote A) since
>> >> the reader returns exactly the same result either way.
>> > Sorry, is that a no?
>> It's not just a "no", it's a "no, because it's impossible".
>> I thought that would be obvious to a seasoned Lisper like you, but
>> clearly it isn't so we need to say it more explicitly.
> pcase isn't Lisp, it's a macro that assigns different meanings to some
> Lisp constructs.
But it's defined as a macro in Lisp. Macros in Lisp do not see the
source code's text, they only see the Sexp representation, so just like
they can't see how much whitespace or which comments were present, they
can't distinguish 'foo from (quote foo) since they're both turned by the
Lisp reader into a cons cells with the symbol `quote' in the car.
>> -The @var{pattern} part of a clause can be of one of two types:
>> -@dfn{QPattern}, a pattern quoted with a backquote; or a
>> -@dfn{UPattern}, which is not quoted. UPatterns are simpler, so we
>> -describe them first.
> If we use "backquoted patterns" here, the rest does have a purpose,
> and removing it diminishes the ease of reading, I think. The purpose
> of this was to provide some outlook on the issue that's about to be
> described.
OK.
>> -The QPatterns are more powerful. They allow matching the value of the
>> -@var{expression} that is the first argument of @code{pcase} against
>> -specifications of its @emph{structure}. For example, you can specify
>> -that the value must be a list of 2 elements whose first element is a
>> -string and the second element is a number. QPatterns can have one of
>> -the following forms:
>> +@node Pcase with backquotes
>> +@subsubsection Pcase with backquotes
>> +
>> +Additionally to the above patterns, one can also use a backquoted
>> +pattern. This facility is designed with the idea that a backquoted
>> +pattern should match all values that could be constructed
>> +by a similarly backquoted expression. For example, you can specify
>> +that the value must be a list of 2 elements whose first element is the
>> +string @code{"first"} with a pattern like @code{`("first" ,elem)}.
> I agree that your example is better, but why the other changes? Why
> is it important to tell the reader the design idea?
I thought it would be good to try and give them an intuition that
hopefully helps them see the correspondance between the normal backquote
macro and the pcase backquote macro.
> I also don't think further dividing this sub-section into
> sub-sub-sections is a good idea: there are less than 200 lines in it,
> so it's not too large. The last sub-sub-section you holds just 6
> lines, way to few to justify a separate unit, I think.
OK.
> In general, subdividing into nodes breaks the continuity of
> description, so it's only justified for significant portions or for
> some obscure aspect (like an extended footnote), or for almost
> entirely unrelated subjects. None of that happens here, I think.
I guess I like structure more than the average human.
Stefan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-23 11:17 ` Update of pcase docs for the elisp manual Eli Zaretskii
2016-01-24 4:40 ` Stefan Monnier
2016-01-25 14:15 ` Michael Heerdegen
@ 2016-01-26 16:59 ` John Wiegley
2016-01-26 18:10 ` Stefan Monnier
2016-01-26 18:41 ` Eli Zaretskii
2 siblings, 2 replies; 28+ messages in thread
From: John Wiegley @ 2016-01-26 16:59 UTC (permalink / raw
To: Eli Zaretskii; +Cc: Michael Heerdegen, emacs-devel
>>>>> Eli Zaretskii <eliz@gnu.org> writes:
> I updated the docs, thanks to both of you. I used your text, John, and also
> Michael's pcase-guide.el as the starting points, source of inspiration and
> examples, and sometimes source of swaths of text as well. I also used what
> was already in the manual. The end result, for which I accept full
> responsibility (although you are named as co-authors), is in the repository;
> please take a look and comment, modify, and improve as appropriate. In
> particular, the UPattern example needs to be improved as the comment there
> says, please do so if you have time.
Thanks Eli, just two questions from me:
- Is there any way we can get rid of the phrases QPattern and UPattern?
There's decades of prior literature on pattern matching in functional
languages, and none of them use "QPattern" and "UPattern". We're inventing
terms that make no sense at all to newcomers, except for the single-letter
correspondence with "quoted" and "unquoted". What if we just call them
"quoted patterns" and "unquoted patterns", if that is what we mean?
I still vote for "literal" and "logical", since a literal pattern matches
by literally being the same value as the input, while a logical pattern
matches due to the logic of the pattern.
- The docs say "UPatterns are simpler, so we describe them first." Don't
UPatterns represent the entire complexity of `pcase'? How are they
simpler?
--
John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 16:59 ` John Wiegley
@ 2016-01-26 18:10 ` Stefan Monnier
2016-01-26 18:41 ` Eli Zaretskii
1 sibling, 0 replies; 28+ messages in thread
From: Stefan Monnier @ 2016-01-26 18:10 UTC (permalink / raw
To: emacs-devel
> - Is there any way we can get rid of the phrases QPattern and UPattern?
> There's decades of prior literature on pattern matching in functional
> languages, and none of them use "QPattern" and "UPattern". We're inventing
> terms that make no sense at all to newcomers, except for the single-letter
> correspondence with "quoted" and "unquoted". What if we just call them
> "quoted patterns" and "unquoted patterns", if that is what we mean?
FWIW, in the current docsring of pcase I just call unquoted patterns
"patterns" (what an idea, eh?), but I still use "QPAT" in the part that
describes the backquote pattern.
Stefan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 16:59 ` John Wiegley
2016-01-26 18:10 ` Stefan Monnier
@ 2016-01-26 18:41 ` Eli Zaretskii
2016-01-26 19:35 ` John Wiegley
2016-01-26 19:58 ` Andy Moreton
1 sibling, 2 replies; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-26 18:41 UTC (permalink / raw
To: John Wiegley; +Cc: michael_heerdegen, emacs-devel
> From: John Wiegley <jwiegley@gmail.com>
> Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org
> Date: Tue, 26 Jan 2016 08:59:42 -0800
>
> - Is there any way we can get rid of the phrases QPattern and UPattern?
> There's decades of prior literature on pattern matching in functional
> languages, and none of them use "QPattern" and "UPattern". We're inventing
> terms that make no sense at all to newcomers, except for the single-letter
> correspondence with "quoted" and "unquoted". What if we just call them
> "quoted patterns" and "unquoted patterns", if that is what we mean?
The alternatives you propose are longer, which makes it harder to
produce palatable descriptions. And there's a long tradition of using
them in Emacs.
But I don't own the manual; if you want to get rid of those terms, go
ahead and make the change.
> I still vote for "literal" and "logical", since a literal pattern matches
> by literally being the same value as the input, while a logical pattern
> matches due to the logic of the pattern.
AFAIU, your division into logical and literal was different from the
division between UPatterns and QPatterns. That's why I didn't use
those terms.
> - The docs say "UPatterns are simpler, so we describe them first." Don't
> UPatterns represent the entire complexity of `pcase'?
On the implementation level, yes. But that's not really relevant for
the documentation (except that we really should say so and give an
example).
> How are they simpler?
They are to me. They use undecorated symbols, and don't require the
quote/unquote games. If that doesn't explain why they are simpler,
then I don't know how to explain it, but the gut feeling is very real.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 18:41 ` Eli Zaretskii
@ 2016-01-26 19:35 ` John Wiegley
2016-01-26 20:28 ` Eli Zaretskii
2016-01-26 19:58 ` Andy Moreton
1 sibling, 1 reply; 28+ messages in thread
From: John Wiegley @ 2016-01-26 19:35 UTC (permalink / raw
To: Eli Zaretskii; +Cc: michael_heerdegen, emacs-devel
>>>>> Eli Zaretskii <eliz@gnu.org> writes:
> The alternatives you propose are longer, which makes it harder to produce
> palatable descriptions. And there's a long tradition of using them in Emacs.
> But I don't own the manual; if you want to get rid of those terms, go ahead
> and make the change.
I'll give it some more thought.
>> I still vote for "literal" and "logical", since a literal pattern matches
>> by literally being the same value as the input, while a logical pattern
>> matches due to the logic of the pattern.
> AFAIU, your division into logical and literal was different from the
> division between UPatterns and QPatterns. That's why I didn't use those
> terms.
Could you explain a bit more how they were different? Such variance was
intended.
>> How are they simpler?
> They are to me. They use undecorated symbols, and don't require the
> quote/unquote games. If that doesn't explain why they are simpler, then I
> don't know how to explain it, but the gut feeling is very real.
Ah, so they are syntactical simpler, but not semantically simpler. Hmm. Maybe
we should drop the statement about simplicity and just say we're presenting
UPatterns first.
--
John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 18:41 ` Eli Zaretskii
2016-01-26 19:35 ` John Wiegley
@ 2016-01-26 19:58 ` Andy Moreton
2016-01-26 20:19 ` Eli Zaretskii
1 sibling, 1 reply; 28+ messages in thread
From: Andy Moreton @ 2016-01-26 19:58 UTC (permalink / raw
To: emacs-devel
On Tue 26 Jan 2016, Eli Zaretskii wrote:
>> From: John Wiegley <jwiegley@gmail.com>
>> Cc: Michael Heerdegen <michael_heerdegen@web.de>, emacs-devel@gnu.org
>> Date: Tue, 26 Jan 2016 08:59:42 -0800
>>
>> - Is there any way we can get rid of the phrases QPattern and UPattern?
>> There's decades of prior literature on pattern matching in functional
>> languages, and none of them use "QPattern" and "UPattern". We're inventing
>> terms that make no sense at all to newcomers, except for the single-letter
>> correspondence with "quoted" and "unquoted". What if we just call them
>> "quoted patterns" and "unquoted patterns", if that is what we mean?
>
> The alternatives you propose are longer, which makes it harder to
> produce palatable descriptions. And there's a long tradition of using
> them in Emacs.
>
> But I don't own the manual; if you want to get rid of those terms, go
> ahead and make the change.
>
>> I still vote for "literal" and "logical", since a literal pattern matches
>> by literally being the same value as the input, while a logical pattern
>> matches due to the logic of the pattern.
>
> AFAIU, your division into logical and literal was different from the
> division between UPatterns and QPatterns. That's why I didn't use
> those terms.
>
>> - The docs say "UPatterns are simpler, so we describe them first." Don't
>> UPatterns represent the entire complexity of `pcase'?
>
> On the implementation level, yes. But that's not really relevant for
> the documentation (except that we really should say so and give an
> example).
>
>> How are they simpler?
>
> They are to me. They use undecorated symbols, and don't require the
> quote/unquote games. If that doesn't explain why they are simpler,
> then I don't know how to explain it, but the gut feeling is very real.
It seems to me that the distinction in the pcase interface is between
primitive patterns that are irreducible, and composite patterns that are
built by composing primitive patterns.
The pcase_defmacro machinery appears to offer syntactic convenience but
does not offer anything that could not be expressed more verbosely using
more primitive patterns.
The other thing that is important for documentation is that each pattern
needs to describe what the pattern matches, and what bindings are made
if the pattern matches.
Of course I am not an experienced macrologist, but an ordinary emacs
user trying to make sense of how pcase works.
Many thanks to Eli et al for trying to make all of this clearer!
AndyM
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 19:58 ` Andy Moreton
@ 2016-01-26 20:19 ` Eli Zaretskii
0 siblings, 0 replies; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-26 20:19 UTC (permalink / raw
To: Andy Moreton; +Cc: emacs-devel
> From: Andy Moreton <andrewjmoreton@gmail.com>
> Date: Tue, 26 Jan 2016 19:58:30 +0000
>
> >> - The docs say "UPatterns are simpler, so we describe them first." Don't
> >> UPatterns represent the entire complexity of `pcase'?
> >
> > On the implementation level, yes. But that's not really relevant for
> > the documentation (except that we really should say so and give an
> > example).
> >
> >> How are they simpler?
> >
> > They are to me. They use undecorated symbols, and don't require the
> > quote/unquote games. If that doesn't explain why they are simpler,
> > then I don't know how to explain it, but the gut feeling is very real.
>
> It seems to me that the distinction in the pcase interface is between
> primitive patterns that are irreducible, and composite patterns that are
> built by composing primitive patterns.
That's one possible way of looking at the issue. But to me it doesn't
make a lot of sense, because when I learn a new tool, I don't
necessarily want to study its internal design right there and then.
First, I want to learn to use it. And for that, the required mental
model doesn't need to reflect the internals too closely, and doesn't
have to be mathematically rigorous. It just needs to make sense.
> The other thing that is important for documentation is that each pattern
> needs to describe what the pattern matches, and what bindings are made
> if the pattern matches.
I hope that's exactly what I did.
> Of course I am not an experienced macrologist, but an ordinary emacs
> user trying to make sense of how pcase works.
I tried to look at the issue through the eyes of such a user.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 19:35 ` John Wiegley
@ 2016-01-26 20:28 ` Eli Zaretskii
2016-01-29 1:28 ` John Wiegley
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-26 20:28 UTC (permalink / raw
To: John Wiegley; +Cc: michael_heerdegen, emacs-devel
> From: John Wiegley <jwiegley@gmail.com>
> Cc: michael_heerdegen@web.de, emacs-devel@gnu.org
> Date: Tue, 26 Jan 2016 11:35:37 -0800
>
> >> I still vote for "literal" and "logical", since a literal pattern matches
> >> by literally being the same value as the input, while a logical pattern
> >> matches due to the logic of the pattern.
>
> > AFAIU, your division into logical and literal was different from the
> > division between UPatterns and QPatterns. That's why I didn't use those
> > terms.
>
> Could you explain a bit more how they were different? Such variance was
> intended.
Sorry, I didn't keep your text after I finished working on this. If
you send it to me again, I will try to explain.
> >> How are they simpler?
>
> > They are to me. They use undecorated symbols, and don't require the
> > quote/unquote games. If that doesn't explain why they are simpler, then I
> > don't know how to explain it, but the gut feeling is very real.
>
> Ah, so they are syntactical simpler, but not semantically simpler.
No, they are also semantically different: they allow more generalized
matching rules.
> Hmm. Maybe we should drop the statement about simplicity and just
> say we're presenting UPatterns first.
Like I said: I don't own the manual...
I do wonder why these minor nits trigger such a large portion of the
comments. They are there to make the text easier to read, so it isn't
too dry. If people dislike that style, it's fine with me to delete
those parts, but what about "the meat"? Did I succeed to write
something that can be studied and learned from?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-25 16:33 ` Eli Zaretskii
@ 2016-01-28 18:37 ` Michael Heerdegen
2016-01-29 3:06 ` Stefan Monnier
2016-01-29 9:45 ` Eli Zaretskii
0 siblings, 2 replies; 28+ messages in thread
From: Michael Heerdegen @ 2016-01-28 18:37 UTC (permalink / raw
To: Eli Zaretskii; +Cc: johnw, emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> I understand. I'm just saying that it would be better to provide an
> example of using 'let' which actually made use of the reason for its
> introduction: binding symbols to values.
It's not easy to find an example for a usage of the let pattern that is
not too complicated and can't be replaced trivially with other patterns,
and does also make at least a bit of sense.
I maybe would suggest something like this:
--8<---------------cut here---------------start------------->8---
(pcase some-list
((and (let value (calculate-some-value))
(or (pred (member value))
(pred (assoc value))))
value))
--8<---------------cut here---------------end--------------->8---
This tests some-list whether - for a VALUE calculated and bound in a let
pattern, whether either this VALUE is a member of the argument list, or
a key in it interpreted as an alist. If it is, that value is returned.
How is the state of the documentation now? Do you need some more
contributions, or should I proofread everything?
Regards,
Michael.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-26 20:28 ` Eli Zaretskii
@ 2016-01-29 1:28 ` John Wiegley
2016-01-29 8:30 ` Eli Zaretskii
0 siblings, 1 reply; 28+ messages in thread
From: John Wiegley @ 2016-01-29 1:28 UTC (permalink / raw
To: Eli Zaretskii; +Cc: michael_heerdegen, emacs-devel
>>>>> Eli Zaretskii <eliz@gnu.org> writes:
>> > AFAIU, your division into logical and literal was different from the
>> > division between UPatterns and QPatterns. That's why I didn't use those
>> > terms.
>>
>> Could you explain a bit more how they were different? Such variance was
>> intended.
> Sorry, I didn't keep your text after I finished working on this. If you send
> it to me again, I will try to explain.
All I meant is, as far as I can tell, UPattern = logical, and QPattern =
literal, without any variation. So isn't it just a name substitution, and
isn't that better than UPattern and QPattern?
>> Ah, so they are syntactical simpler, but not semantically simpler.
> No, they are also semantically different: they allow more generalized
> matching rules.
Different yes, but that's not simpler. The rules for understanding what a
quoted pattern will do are incredibly trivial: it matches per eq with the
scrutinee at that position. The rules of understanding what a UPattern will
do are far more complicated, and can even be extended use pcase-defmacro.
>> Hmm. Maybe we should drop the statement about simplicity and just say we're
>> presenting UPatterns first.
> Like I said: I don't own the manual...
> I do wonder why these minor nits trigger such a large portion of the
> comments. They are there to make the text easier to read, so it isn't too
> dry. If people dislike that style, it's fine with me to delete those parts,
> but what about "the meat"? Did I succeed to write something that can be
> studied and learned from?
Anything, really, is a move forward from what we had before. It's sufficient
for 25.1 in my opinion.
--
John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-28 18:37 ` Michael Heerdegen
@ 2016-01-29 3:06 ` Stefan Monnier
2016-01-29 9:45 ` Eli Zaretskii
1 sibling, 0 replies; 28+ messages in thread
From: Stefan Monnier @ 2016-01-29 3:06 UTC (permalink / raw
To: emacs-devel
> It's not easy to find an example for a usage of the let pattern that is
> not too complicated and can't be replaced trivially with other patterns,
> and does also make at least a bit of sense.
The original motivation of `let' was in order to add a "missing" binding
in some `or' branches. E.g.:
(pcase foo
((or `(key . ,val) (let val 5)) val))
-- Stefan
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 1:28 ` John Wiegley
@ 2016-01-29 8:30 ` Eli Zaretskii
2016-01-29 13:39 ` Andy Moreton
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-29 8:30 UTC (permalink / raw
To: John Wiegley; +Cc: michael_heerdegen, emacs-devel
> From: John Wiegley <jwiegley@gmail.com>
> Cc: michael_heerdegen@web.de, emacs-devel@gnu.org
> Date: Thu, 28 Jan 2016 17:28:30 -0800
>
> >>>>> Eli Zaretskii <eliz@gnu.org> writes:
>
> >> > AFAIU, your division into logical and literal was different from the
> >> > division between UPatterns and QPatterns. That's why I didn't use those
> >> > terms.
> >>
> >> Could you explain a bit more how they were different? Such variance was
> >> intended.
>
> > Sorry, I didn't keep your text after I finished working on this. If you send
> > it to me again, I will try to explain.
>
> All I meant is, as far as I can tell, UPattern = logical, and QPattern =
> literal, without any variation.
That's not my recollection, but I no longer have the text to prove it.
> >> Ah, so they are syntactical simpler, but not semantically simpler.
>
> > No, they are also semantically different: they allow more generalized
> > matching rules.
>
> Different yes, but that's not simpler.
Generalizations are almost always more complex than more specific
cases.
> The rules for understanding what a quoted pattern will do are
> incredibly trivial: it matches per eq with the scrutinee at that
> position.
That's not true. You have these:
`(QPAT . ...
`[QPAT ...
and also
`(,UPAT
which break your simplistic rule. (I understand what you want to say,
but saying it in as simplified manner as you did will produce many
errors in actual usage, because it omits crucial details.)
> The rules of understanding what a UPattern will
> do are far more complicated, and can even be extended use pcase-defmacro.
But each UPattern rule, taken alone, is quite simple.
> > I do wonder why these minor nits trigger such a large portion of the
> > comments. They are there to make the text easier to read, so it isn't too
> > dry. If people dislike that style, it's fine with me to delete those parts,
> > but what about "the meat"? Did I succeed to write something that can be
> > studied and learned from?
>
> Anything, really, is a move forward from what we had before. It's sufficient
> for 25.1 in my opinion.
Thanks.
I will make a few final corrections soon, based on these discussions,
and then I'm done with that part of the manual.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-28 18:37 ` Michael Heerdegen
2016-01-29 3:06 ` Stefan Monnier
@ 2016-01-29 9:45 ` Eli Zaretskii
2016-01-29 14:51 ` Michael Heerdegen
1 sibling, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-29 9:45 UTC (permalink / raw
To: Michael Heerdegen; +Cc: johnw, emacs-devel
> From: Michael Heerdegen <michael_heerdegen@web.de>
> Cc: johnw@gnu.org, emacs-devel@gnu.org
> Date: Thu, 28 Jan 2016 19:37:50 +0100
>
> > I understand. I'm just saying that it would be better to provide an
> > example of using 'let' which actually made use of the reason for its
> > introduction: binding symbols to values.
>
> It's not easy to find an example for a usage of the let pattern that is
> not too complicated and can't be replaced trivially with other patterns,
> and does also make at least a bit of sense.
>
> I maybe would suggest something like this:
>
> --8<---------------cut here---------------start------------->8---
> (pcase some-list
> ((and (let value (calculate-some-value))
> (or (pred (member value))
> (pred (assoc value))))
> value))
> --8<---------------cut here---------------end--------------->8---
Thanks. I went with Stefan's example instead.
> How is the state of the documentation now? Do you need some more
> contributions, or should I proofread everything?
I'm done adjudicating all the comments, see commit d7a93ef.
In this message:
http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg01404.html
I asked for an example of rewriting a QPattern-based example using
only UPatterns; perhaps you could contribute such an example for the
manual. And, of course, any other comments and patches are welcome.
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 8:30 ` Eli Zaretskii
@ 2016-01-29 13:39 ` Andy Moreton
2016-01-29 14:21 ` Eli Zaretskii
0 siblings, 1 reply; 28+ messages in thread
From: Andy Moreton @ 2016-01-29 13:39 UTC (permalink / raw
To: emacs-devel
On Fri 29 Jan 2016, Eli Zaretskii wrote:
>
> I will make a few final corrections soon, based on these discussions,
> and then I'm done with that part of the manual.
Thanks for your efforts to improve the documentation.
In (info "(elisp) Pattern matching case statement") we currently have:
"The ‘cond’ form lets you choose between alternatives using predicate
conditions that compare values of expressions against specific values
known and written in advance. However, sometimes it is useful to select
alternatives based on more general conditions that distinguish between
broad classes of values. The ‘pcase’ macro allows you to choose between
alternatives based on matching the value of an expression against a
series of patterns. A pattern can be a literal value (for comparisons
to literal values you’d use ‘cond’), or it can be a more general
description of the expected structure of the expression’s value."
I think this would be clearer without the initial discussion of cond:
"The ‘pcase’ macro allows you to choose between alternatives based on
matching the value of an expression against a series of patterns. A
pattern can be a literal value (for comparisons to literal values you’d
use ‘cond’), or it can be a more general description of the expected
structure of the expression’s value."
This gets straight to saying what pcase is useful for (and when cond is
sufficient for the task).
Also, the description of CLAUSES for pcase and cond in the manual use:
pcase: (PATTERN BODY-FORMS…)
cond: (CONDITION BODY-FORMS…)
However the doc strings are inconsistent with the manual:
pcase: (PATTERN CODE...)
cond: (CONDITION BODY...)
It would be better to use consistent terms.
AndyM
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 13:39 ` Andy Moreton
@ 2016-01-29 14:21 ` Eli Zaretskii
2016-01-29 15:14 ` Andy Moreton
0 siblings, 1 reply; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-29 14:21 UTC (permalink / raw
To: Andy Moreton; +Cc: emacs-devel
> From: Andy Moreton <andrewjmoreton@gmail.com>
> Date: Fri, 29 Jan 2016 13:39:59 +0000
>
> In (info "(elisp) Pattern matching case statement") we currently have:
>
> "The ‘cond’ form lets you choose between alternatives using predicate
> conditions that compare values of expressions against specific values
> known and written in advance. However, sometimes it is useful to select
> alternatives based on more general conditions that distinguish between
> broad classes of values. The ‘pcase’ macro allows you to choose between
> alternatives based on matching the value of an expression against a
> series of patterns. A pattern can be a literal value (for comparisons
> to literal values you’d use ‘cond’), or it can be a more general
> description of the expected structure of the expression’s value."
>
> I think this would be clearer without the initial discussion of cond:
>
> "The ‘pcase’ macro allows you to choose between alternatives based on
> matching the value of an expression against a series of patterns. A
> pattern can be a literal value (for comparisons to literal values you’d
> use ‘cond’), or it can be a more general description of the expected
> structure of the expression’s value."
>
> This gets straight to saying what pcase is useful for (and when cond is
> sufficient for the task).
I obviously disagree, or else I wouldn't have written that in the
first place.
I think 'pcase' deserves a rationale, and contrasting it with another
similar facility is a good way of presenting that rationale, and at
the same time making the point that 'pcase' shouldn't be used where
'cond' can do the job, something that came up in the recent
discussions.
> Also, the description of CLAUSES for pcase and cond in the manual use:
> pcase: (PATTERN BODY-FORMS…)
> cond: (CONDITION BODY-FORMS…)
>
> However the doc strings are inconsistent with the manual:
> pcase: (PATTERN CODE...)
> cond: (CONDITION BODY...)
>
> It would be better to use consistent terms.
Blame those who wrote the doc strings ;-)
Thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 9:45 ` Eli Zaretskii
@ 2016-01-29 14:51 ` Michael Heerdegen
0 siblings, 0 replies; 28+ messages in thread
From: Michael Heerdegen @ 2016-01-29 14:51 UTC (permalink / raw
To: emacs-devel
Eli Zaretskii <eliz@gnu.org> writes:
> In this message:
>
> http://lists.gnu.org/archive/html/emacs-devel/2016-01/msg01404.html
>
> I asked for an example of rewriting a QPattern-based example using
> only UPatterns; perhaps you could contribute such an example for the
> manual.
Ok, let's discuss this under the example Stefan gave in
<jwvd1skxyr2.fsf-monnier+emacsdiffs@gnu.org>, if you think the example
there not didactically appropriate.
Regards,
Michael.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 14:21 ` Eli Zaretskii
@ 2016-01-29 15:14 ` Andy Moreton
2016-01-29 15:37 ` Eli Zaretskii
0 siblings, 1 reply; 28+ messages in thread
From: Andy Moreton @ 2016-01-29 15:14 UTC (permalink / raw
To: emacs-devel
On Fri 29 Jan 2016, Eli Zaretskii wrote:
>> From: Andy Moreton <andrewjmoreton@gmail.com>
>> Date: Fri, 29 Jan 2016 13:39:59 +0000
>>
>> This gets straight to saying what pcase is useful for (and when cond is
>> sufficient for the task).
>
> I obviously disagree, or else I wouldn't have written that in the
> first place.
>
> I think 'pcase' deserves a rationale, and contrasting it with another
> similar facility is a good way of presenting that rationale, and at
> the same time making the point that 'pcase' shouldn't be used where
> 'cond' can do the job, something that came up in the recent
> discussions.
Fair enough. Please consider starting a new paragraph though:
"The ‘cond’ form lets you choose between alternatives using predicate
conditions that compare values of expressions against specific values
known and written in advance. However, sometimes it is useful to select
alternatives based on more general conditions that distinguish between
broad classes of values.
The ‘pcase’ macro allows you to choose between alternatives based on
matching the value of an expression against a series of patterns. A
pattern can be a literal value (for comparisons to literal values you’d
use ‘cond’), or it can be a more general description of the expected
structure of the expression’s value."
>> Also, the description of CLAUSES for pcase and cond in the manual use:
>> pcase: (PATTERN BODY-FORMS…)
>> cond: (CONDITION BODY-FORMS…)
>>
>> However the doc strings are inconsistent with the manual:
>> pcase: (PATTERN CODE...)
>> cond: (CONDITION BODY...)
>>
>> It would be better to use consistent terms.
>
> Blame those who wrote the doc strings ;-)
I sought improvement, not blame :-)
AndyM
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: Update of pcase docs for the elisp manual
2016-01-29 15:14 ` Andy Moreton
@ 2016-01-29 15:37 ` Eli Zaretskii
0 siblings, 0 replies; 28+ messages in thread
From: Eli Zaretskii @ 2016-01-29 15:37 UTC (permalink / raw
To: Andy Moreton; +Cc: emacs-devel
> From: Andy Moreton <andrewjmoreton@gmail.com>
> Date: Fri, 29 Jan 2016 15:14:17 +0000
>
> Fair enough. Please consider starting a new paragraph though:
>
> "The ‘cond’ form lets you choose between alternatives using predicate
> conditions that compare values of expressions against specific values
> known and written in advance. However, sometimes it is useful to select
> alternatives based on more general conditions that distinguish between
> broad classes of values.
>
> The ‘pcase’ macro allows you to choose between alternatives based on
> matching the value of an expression against a series of patterns. A
> pattern can be a literal value (for comparisons to literal values you’d
> use ‘cond’), or it can be a more general description of the expected
> structure of the expression’s value."
Fine with me, thanks. Feel free to commit.
> >> However the doc strings are inconsistent with the manual:
> >> pcase: (PATTERN CODE...)
> >> cond: (CONDITION BODY...)
> >>
> >> It would be better to use consistent terms.
> >
> > Blame those who wrote the doc strings ;-)
>
> I sought improvement, not blame :-)
Feel free to improve the doc strings in that direction, and thanks.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2016-01-29 15:37 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <m2fuxq6pb0.fsf@newartisans.com>
[not found] ` <87d1stznc6.fsf@web.de>
[not found] ` <m2si1p8r31.fsf@newartisans.com>
[not found] ` <m2powt5w50.fsf@newartisans.com>
2016-01-23 11:17 ` Update of pcase docs for the elisp manual Eli Zaretskii
2016-01-24 4:40 ` Stefan Monnier
2016-01-24 14:33 ` Eli Zaretskii
2016-01-24 23:17 ` Stefan Monnier
2016-01-25 16:14 ` Eli Zaretskii
2016-01-26 1:40 ` Stefan Monnier
2016-01-26 15:38 ` Eli Zaretskii
2016-01-26 16:23 ` Stefan Monnier
2016-01-25 14:22 ` Michael Heerdegen
2016-01-25 14:15 ` Michael Heerdegen
2016-01-25 16:33 ` Eli Zaretskii
2016-01-28 18:37 ` Michael Heerdegen
2016-01-29 3:06 ` Stefan Monnier
2016-01-29 9:45 ` Eli Zaretskii
2016-01-29 14:51 ` Michael Heerdegen
2016-01-26 16:59 ` John Wiegley
2016-01-26 18:10 ` Stefan Monnier
2016-01-26 18:41 ` Eli Zaretskii
2016-01-26 19:35 ` John Wiegley
2016-01-26 20:28 ` Eli Zaretskii
2016-01-29 1:28 ` John Wiegley
2016-01-29 8:30 ` Eli Zaretskii
2016-01-29 13:39 ` Andy Moreton
2016-01-29 14:21 ` Eli Zaretskii
2016-01-29 15:14 ` Andy Moreton
2016-01-29 15:37 ` Eli Zaretskii
2016-01-26 19:58 ` Andy Moreton
2016-01-26 20:19 ` Eli Zaretskii
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.