emacs-devel
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]