unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Michael Heerdegen <michael_heerdegen@web.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: jwiegley@gmail.com, emacs-devel@gnu.org
Subject: Re: pcase docs
Date: Sat, 23 Jan 2016 15:22:08 +0100	[thread overview]
Message-ID: <87vb6k8jfz.fsf@web.de> (raw)
In-Reply-To: <8360yk5sgm.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 23 Jan 2016 15:35:37 +0200")

Eli Zaretskii <eliz@gnu.org> writes:

> > Surely not!  I just had the time to read the code, carefully (I had to,
> > to be able to write my el-search.el thing).  Most others don't care
> > because they just don't care, I think.
>
> But this stuff is widely used, by several different individuals.  How
> do they know what to put in the code, if they, like me, are confused
> about the purpose and the usage?

Dunno.  If it helps: I had spent really a lot of time into understanding
pcase.  More time than you can probably invest, doing all the work you
do.  And I made lots of errors over weeks after had finally internalized
everything.

> > Actually `pcase-defmacro' is easy to understand if you understood
> > `defmacro': You define a pattern by its name and by the arguments it
> > will accept.
>
> But 'pcase' patterns don't accept any arguments, they are matched
> against a value of an expression.  So how to understand "arguments" in
> this context?

pcase-defmacro can only define patterns that are used like function
calls, (pattern-name pattern-args), like

 
  (pred fun)
  (guard expr)
  (or pattern...)

In the sense of pcase-defmacro, FUN, EXPR or the PATTERNs play the role
of arguments of the pattern.

> > When the pcase "compiler" finds a pattern that is defined as a
> > macro, it substitutes the "call" with the "code" returned by
> > evaluating the macro definition with the given arguments.
>
> What do you mean by "call" here?

A usage, or appearance, of the pattern.


> And how to explain that a pattern that starts with "`(list" will
> somehow end up using the pattern defined with "(pcase-defmacro map"?

No, `map' doesn't define `, it defines a pattern named `map' (that
currently is rarely used, or nowhere).

Mmh, maybe you need just a simple example.  Let's define a pcase pattern
"greater-than" that matches any number greater than a specified one, so
that e.g.

(pcase 9
  ((greater-than 2) t))  ==> t

but

(pcase (+ 0 1)
  ((greater-than (* 2 5)) t))  ==> nil.

or

(pcase "Hallo"
  ((greater-than 2) t))  ==> nil.

You could define it like this:

(pcase-defmacro greater-than (number)
  `(and (pred numberp)
        (pred (lambda (x) (< ,number x)))))

Then any occurrence of (greater-than N) in any pcase pattern is simply
substituted with

  (and (pred numberp)
       (pred (lambda (x) (< N x))))

That's it.


Of course, the variable name "x" in the above definition could lead to
name clashes (as with "conventional" macros), so you would better use an
uninterned symbol.  But with the shortcut version of `pred', we instead
can just write

(pcase-defmacro greater-than (number)
  `(and (pred numberp) (pred (< ,number))))

and avoid that problem this way.


A different simple example: here is how you could define `guard' via
`pred':

(pcase-defmacro guard (expr)
  `(pred ,(lambda () expr)))


HTH,

Michael.



  reply	other threads:[~2016-01-23 14:22 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-14 19:47 pcase docs Eli Zaretskii
2016-01-22 18:07 ` John Wiegley
2016-01-22 19:46   ` Michael Heerdegen
2016-01-22 19:58     ` Michael Heerdegen
2016-01-22 21:30       ` Eli Zaretskii
2016-01-23 10:16         ` Michael Heerdegen
2016-01-23 11:43           ` Eli Zaretskii
2016-01-23 12:05             ` Michael Heerdegen
2016-01-23 13:35               ` Eli Zaretskii
2016-01-23 14:22                 ` Michael Heerdegen [this message]
2016-01-23 14:50                   ` Eli Zaretskii
2016-01-23 15:18                     ` Michael Heerdegen
2016-01-24  8:50                       ` Nicolas Petton
2016-01-23 15:51                 ` Michael Heerdegen
2016-01-23 12:28             ` Alan Mackenzie
2016-01-23 13:13               ` Eli Zaretskii
2016-01-23 20:48               ` Drew Adams
2016-01-24  5:07             ` Stefan Monnier
2016-01-22 21:28     ` 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=87vb6k8jfz.fsf@web.de \
    --to=michael_heerdegen@web.de \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=jwiegley@gmail.com \
    /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).