[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Update of pcase docs for the elisp manual
From: |
Stefan Monnier |
Subject: |
Re: Update of pcase docs for the elisp manual |
Date: |
Mon, 25 Jan 2016 20:40:12 -0500 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.1.50 (gnu/linux) |
> 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:
address@hidden, a pattern quoted with a backquote; or a
address@hidden, 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
address@hidden 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:
address@hidden Pcase with backquotes
address@hidden 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 @address@hidden where
address@hidden can have the following forms:
@table @code
address@hidden `(@var{qpattern1} . @var{qpattern2})
address@hidden (@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}.
address@hidden address@hidden @var{qpattern2} @dots{} @var{qpatternm}]
+This generalizes to (@var{qpattern1} @var{qpattern2} @dots{}
address@hidden), of course.
address@hidden address@hidden @var{qpattern2} @dots{} @var{qpatternm}]
Matches if the value being matched is a vector of length @var{m} whose
@address@hidden(@var{m}-1)}th elements match @var{qpattern1},
@var{qpattern2} @dots{} @var{qpatternm}, respectively.
address@hidden `(,@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
address@hidden Pcase example
address@hidden 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
address@hidden Pcase macros
address@hidden 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
address@hidden are bound to @var{actual-args}.
@end defmac
@node Combining Conditions
Re: Update of pcase docs for the elisp manual, Michael Heerdegen, 2016/01/25
Re: Update of pcase docs for the elisp manual, John Wiegley, 2016/01/26