From: Alan Mackenzie <acm@muc.de>
To: emacs-devel@gnu.org
Subject: "Like `let*' but ....."
Date: Tue, 24 Jan 2017 21:12:27 +0000 [thread overview]
Message-ID: <20170124211227.GC7358@acm> (raw)
Hello, Emacs.
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.
There is no other documentation of pcase-let* that I'm aware of.
Would somebody please explain it to me? In particular, I want to
understand the following form from byte-compile-file-form-defalias in
bytecomp.el:
(pcase-let*
;; `macro' is non-nil if it defines a macro.
;; `fun' is the function part of `arg' (defaults to `arg').
(((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let macro t))
(and (let fun arg) (let macro nil)))
arg)
;; `lam' is the lambda expression in `fun' (or nil if not
;; recognized).
((or `(,(or `quote `function) ,lam) (let lam nil))
fun)
;; `arglist' is the list of arguments (or t if not recognized).
;; `body' is the body of `lam' (or t if not recognized).
((or `(lambda ,arglist . ,body)
;; `(closure ,_ ,arglist . ,body)
(and `(internal-make-closure ,arglist . ,_) (let body t))
(and (let arglist t) (let body t)))
lam))
(unless (byte-compile-file-form-defmumble
name macro arglist body rest)
(when macro
(if (null fun)
(message "Macro %s unrecognized, won't work in file" name)
(message "Macro %s partly recognized, trying our luck" name)
(push (cons name (eval fun))
byte-compile-macro-environment)))
(byte-compile-keep-pending form))))
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?
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)))
(if
(consp x)
(let*
((x
(car x))
(x
(cdr x)))
(if
(null x)
(funcall pcase-0 t x)
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg)))
(funcall pcase-0 nil arg))))
Is this efficient, in either run-time or the size of the byte code produced?
--
Alan Mackenzie (Nuremberg, Germany).
next reply other threads:[~2017-01-24 21:12 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-24 21:12 Alan Mackenzie [this message]
2017-01-24 21:26 ` "Like `let*' but ....." Clément Pit-Claudel
2017-01-27 20:33 ` Alan Mackenzie
2017-01-24 23:10 ` Michael Heerdegen
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
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=20170124211227.GC7358@acm \
--to=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 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).