all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
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.



  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.