From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.devel Subject: "Like `let*' but ....." Date: Tue, 24 Jan 2017 21:12:27 +0000 Message-ID: <20170124211227.GC7358@acm> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: blaine.gmane.org 1485292408 2979 195.159.176.226 (24 Jan 2017 21:13:28 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Tue, 24 Jan 2017 21:13:28 +0000 (UTC) User-Agent: Mutt/1.7.2 (2016-11-26) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jan 24 22:13:23 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cW8P2-00008U-SG for ged-emacs-devel@m.gmane.org; Tue, 24 Jan 2017 22:13:20 +0100 Original-Received: from localhost ([::1]:55800 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cW8P8-0006zt-0Y for ged-emacs-devel@m.gmane.org; Tue, 24 Jan 2017 16:13:26 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:49517) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cW8OZ-0006zo-OL for emacs-devel@gnu.org; Tue, 24 Jan 2017 16:12:53 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cW8OU-0007NM-Qs for emacs-devel@gnu.org; Tue, 24 Jan 2017 16:12:51 -0500 Original-Received: from ocolin.muc.de ([193.149.48.4]:34885 helo=mail.muc.de) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1cW8OU-0007N1-Ld for emacs-devel@gnu.org; Tue, 24 Jan 2017 16:12:46 -0500 Original-Received: (qmail 84287 invoked by uid 3782); 24 Jan 2017 21:12:42 -0000 Original-Received: from acm.muc.de (p548C7CD0.dip0.t-ipconnect.de [84.140.124.208]) by colin.muc.de (tmda-ofmipd) with ESMTP; Tue, 24 Jan 2017 22:12:42 +0100 Original-Received: (qmail 8330 invoked by uid 1000); 24 Jan 2017 21:12:27 -0000 Content-Disposition: inline X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-detected-operating-system: by eggs.gnu.org: FreeBSD 9.x [fuzzy] X-Received-From: 193.149.48.4 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:211587 Archived-At: 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).