emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Replace trivial pcase occurrences in the Emacs sources


From: Stefan Monnier
Subject: Re: Replace trivial pcase occurrences in the Emacs sources
Date: Tue, 30 Oct 2018 15:21:52 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

>> +* Destructuring patterns:: Using pcase patterns to extract subfields.
> We never used "pcase patterns" in the manual before, so I wonder
> whether we should start now.  If we want to do that, this should be
> defined before it is used.

I'm uncomfortable using "pattern" to refer to "pcase pattern" unless the
context makes it clear.  I'm not completely sure where best to define
pcase patterns.

>> address@hidden Destructuring patterns
>> address@hidden Destructuring Patterns
>> address@hidden Destructuring patterns
>
> By convention, index entries should start with a lower-case letter.

Fixed.

>> +The macros described in this section use @emph{destructuring}
>> +patterns, which are normal Pcase patterns used in a context where we
>> +presume that the object does match the pattern, and we only want
>> +to extract some subfields.
>
> I think we need to define "destructuring" here (or elsewhere in the
> manual, and have a cross-reference there in this section).

The paragraph you quoted is exactly what I consider the definition of
"destructuring pattern" (I don't see a need to define "destructuring"
separately: the word placed in front of "pattern" is here treated as
a kind of "proper name", just chosen so that it will help some if they
already know the term from elsewhere, such as cl-destructuring-bind).

> Readers that aren't familiar with that term will not be able to
> understand why this word is used here.  We need to start this with
> something like
>
>   @dfn{Destructuring} means ...

I'd rather rename those to "Monnier patterns" and avoid the problem, if
that's what it takes.

> It would also help to tell what exactly makes a pattern a
> destructuring one.

As the paragraph says: it's the context in which it's used.

> You want the text after the example to start like this:
>
>   @noindent
>   does the same as ...
>
> Otherwise, this sentence sounds awkward, and will also be indented.

Thanks.

>> address@hidden is a list of bindings of the form @code{(@var{pattern}
>> address@hidden)}
>
> Please use @w{..} around this form, so that it doesn't get broken
> between two lines.

Done.

>> +All @var{exp}s are evaluated first after which they are matched
>> +against their respective @var{pattern}, introducing new variable
>> +bindings which can then be used inside @var{body}.
> AFAIU, this means only some of the pcase patterns make sense in this
> context.  If that is true, I'd suggest ti somehow tell which are (or
> which aren't, if that's easier).

Not sure what you're thinking of.

>> address@hidden pcase-dolist (pattern list) address@hidden
>> +This construct executes @var{body} once for each element of
>> address@hidden, in a context where the destructuring pattern
>> address@hidden was matched against the element.
>
> I don't think I understand what "in a context where the pattern was
> matched" means here.  Is any aspect of the match except destructuring
> bindings relevant to execution of the body?

No.  But those extra bindings are exactly the context I'm referring to.
In my work, "context" and "environment" are the usual words used to
refer to the map that links identifiers to their corresponding
information (typically, type or value depending on the
...ahem... context).


        Stefan


diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi
index 5be4b298b4..da6a240ddc 100644
--- a/doc/lispref/control.texi
+++ b/doc/lispref/control.texi
@@ -477,6 +477,7 @@ Pattern-Matching Conditional
 * The @code{pcase} macro: pcase Macro.  Plus examples and caveats.
 * Extending @code{pcase}: Extending pcase.  Define new kinds of patterns.
 * Backquote-Style Patterns: Backquote Patterns.  Structural matching.
+* Destructuring patterns:: Using pcase patterns to extract subfields.
 @end menu
 
 @node pcase Macro
@@ -497,6 +498,10 @@ pcase Macro
 Otherwise, @code{pcase} evaluates to @code{nil}.
 @end defmac
 
+Each @var{pattern} has to be a @dfn{pcase pattern}, which can either
+use one of the core patterns defined below, or use one of the patterns
+defined via @code{pcase-defmacro}.
+
 The rest of this subsection
 describes different forms of core patterns,
 presents some examples,
@@ -1168,6 +1173,82 @@ Backquote Patterns
 (evaluate '(sub 1 2) nil)                 @result{} error
 @end example
 
address@hidden Destructuring patterns
address@hidden Destructuring Patterns
address@hidden destructuring patterns
+
+Pcase patterns not only express a condition on the form of the objects
+they can match but they can also extract sub-fields of those objects.
+Say we have a list and want to extract 2 elements from it with the
+following code:
+
address@hidden
+  (pcase l
+    (`(add ,x ,y)  (message "Contains %S and %S" x y)))
address@hidden example
+
+This will not only extract @code{x} and @code{y} but will additionally
+test that @code{l} is a list containing exactly 3 elements and whose
+first element is the symbol @code{add}.  If any of those tests fail,
address@hidden will directly return @code{nil} without calling
address@hidden
+
+The macros described in this section use @dfn{destructuring
+patterns}, which are normal Pcase patterns used in a context where we
+presume that the object does match the pattern, and we only want
+to extract some subfields.  For example:
+
address@hidden
+  (pcase-let ((`(add ,x ,y) l))
+    (message "Contains %S and %S" x y))
address@hidden example
+
address@hidden
+does the same as the previous example, except that it directly tries
+to extract @code{x} and @code{y} from @code{l} without first verifying
+if @code{l} is a list which has the right number of elements and has
address@hidden as its first element.
+The precise behavior when the object does not actually match the
+pattern is undefined, although the body will not be silently skipped:
+either an error is signaled or the body is run with some of the
+variables potentially bound to arbitrary values like @code{nil}.
+
address@hidden pcase-let bindings address@hidden
+Bind variables according to @var{bindings} and then eval @var{body}.
+
address@hidden is a list of bindings of the form @address@hidden(@var{pattern}
address@hidden)}}, where @var{exp} is an expression to evaluate and
address@hidden is a destructuring pattern.
+
+All @var{exp}s are evaluated first after which they are matched
+against their respective @var{pattern}, introducing new variable
+bindings which can then be used inside @var{body}.
address@hidden defmac
+
address@hidden pcase-let* bindings address@hidden
+Bind variables according to @var{bindings} and then eval @var{body}.
+
address@hidden is a list of bindings of the form @code{(@var{pattern}
address@hidden)}, where @var{exp} is an expression to evaluate and
address@hidden is a destructuring pattern.
+
+Unlike @code{pcase-let}, but like @code{let*}, each @var{exp} is
+matched against its corresponding @var{pattern} before passing to the
+next element of @var{bindings}, so the variables introduced in each
+binding are available in the @var{exp}s that follow it, additionally
+to being available in @var{body}.
address@hidden defmac
+
address@hidden dolist
address@hidden pcase-dolist (pattern list) address@hidden
+This construct executes @var{body} once for each element of
address@hidden, in a context where the destructuring pattern
address@hidden was matched against the element.
+When @var{pattern} is a simple variable, this ends up being equivalent
+to @code{dolist}.
address@hidden defmac
+
+
 @node Iteration
 @section Iteration
 @cindex iteration




reply via email to

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