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: Michael Heerdegen
Subject: Re: Update of pcase docs for the elisp manual
Date: Mon, 25 Jan 2016 15:15:14 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Eli Zaretskii <address@hidden> 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.



reply via email to

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