From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: Update of pcase docs for the elisp manual
Date: Mon, 25 Jan 2016 20:40:12 -0500 [thread overview]
Message-ID: <jwvk2mxws02.fsf-monnier+Inbox@gnu.org> (raw)
In-Reply-To: <83egd53acg.fsf@gnu.org> (Eli Zaretskii's message of "Mon, 25 Jan 2016 18:14:23 +0200")
> 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
next prev parent reply other threads:[~2016-01-26 1:40 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[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 [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=jwvk2mxws02.fsf-monnier+Inbox@gnu.org \
--to=monnier@iro.umontreal.ca \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).