From: Michael Heerdegen <michael_heerdegen@web.de>
To: Alan Mackenzie <acm@muc.de>
Cc: emacs-devel@gnu.org
Subject: Re: "Like `let*' but ....."
Date: Wed, 25 Jan 2017 00:10:11 +0100 [thread overview]
Message-ID: <87lgu0qcks.fsf@web.de> (raw)
In-Reply-To: <20170124211227.GC7358@acm> (Alan Mackenzie's message of "Tue, 24 Jan 2017 21:12:27 +0000")
Hello Alan,
> The doc string of pcase-let* reads, in its entirety:
>
> "Like `let*' but where you can use `pcase' patterns for bindings.
> BODY should be an expression, and BINDINGS should be a list of bindings
> of the form (PAT EXP)."
>
> What is not clear is precisely HOW `pcase' patterns are used for
> bindings, and what the semantics of (PAT EXP) are.
I think Clément's has answered that correctly. And for the semantics of
the patterns see C-h f pcase.
> What eludes me is points such as:
> (i) what variables are being bound?
> (ii) To what values?
> (iii) What do the `or's and `and's on Line 4, etc. mean?
If you are interested in learning to understand `pcase' patterns: if you
want to test what effect matching a pattern against some value has, I
had written the following thing some time ago:
#+begin_src emacs-lisp
(defun my-pcase-matcher (pattern)
"Turn pcase PATTERN into a predicate.
For any given pcase PATTERN, return a predicate P that returns
non-nil for any EXP when and only when PATTERN matches EXP. In
that case, P returns a list of the form (bindings . BINDINGS) as
non-nil value, where BINDINGS is a list of bindings that pattern
matching would actually establish in a pcase branch.
Example:
(setq matcher
(my-pcase-matcher
'`(,(and (pred integerp) x)
,(and (pred integerp)
(pred (< 0))
y))))
(funcall matcher '(1 0))
==> nil
(funcall matcher '(1 2))
==>
(bindings
(x . 1)
(y . 2))"
(let ((arg (make-symbol "exp")))
`(lambda (,arg)
,(pcase--u
`((,(pcase--match arg (pcase--macroexpand pattern))
,(lambda (vars)
`(list
'bindings
,@(nreverse
(mapcar (lambda (pair) `(cons ',(car pair) ,(cdr pair)))
vars))))))))))
#+end_src
> Incidentally, when I expand that form with macroexpand-all and print it
> with pp, the resulting form is 173 lines long, totally inscrutable, a
> typical portion of it looking like this:
>
> (if
> (null x)
> (let*
> ((x
> (cdr x)))
Note that you should bind print-circle -> t and print-gensym -> t when
printing to get a semantically equivalent printed representation of the
macroexpansion.
> Is this efficient, in either run-time or the size of the byte code
> produced?
Those highly nested expressions come from destructuring. I think the
expansion is nearly as effecient as it could be. Dunno about the byte
code size.
Regards,
Michael.
next prev parent reply other threads:[~2017-01-24 23:10 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-24 21:12 "Like `let*' but ....." Alan Mackenzie
2017-01-24 21:26 ` Clément Pit-Claudel
2017-01-27 20:33 ` Alan Mackenzie
2017-01-24 23:10 ` Michael Heerdegen [this message]
2017-01-25 5:08 ` Stefan Monnier
2017-01-27 20:31 ` Alan Mackenzie
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87lgu0qcks.fsf@web.de \
--to=michael_heerdegen@web.de \
--cc=acm@muc.de \
--cc=emacs-devel@gnu.org \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.