unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Michael Heerdegen <michael_heerdegen@web.de>
Cc: emacs-devel@gnu.org
Subject: Re: pcase-setq
Date: Wed, 14 Oct 2015 11:49:43 -0400	[thread overview]
Message-ID: <jwvbnc1a3lf.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <87d1wh36as.fsf@web.de> (Michael Heerdegen's message of "Wed, 14 Oct 2015 15:53:31 +0200")

> (Was it your intention not to CC emacs-dev?  Anyway, I respect it.)

No, I used "reply to all", but there was no emacs-devel in the Cc.
[...hmm...]
Oh, I see there was a "Newsgroups: gmane.emacs.devel" instead, so that's
apparently what caused the problem.

>> It seems to work, indeed.  It could misbehave if you use `guard'
>> or `pred' patterns, but it'd be weird to use them in a `pcase-setq' and
>> the misbehavior is fairly subtle, so I guess overall it's quite OK.
> I'm not sure it would always be weird to use them.  On the contrary, I
> would like that this works, like in (some fantasy example):
>
> --8<---------------cut here---------------start------------->8---
> (defun my-count-chars-in (thing)
>   (pcase-setq (or (and (pred stringp) (app length a))
>                   (and (pred numberp) (let a 1))
>                   (guard (error "No characters here to count")))
>               thing))
> --8<---------------cut here---------------end--------------->8---
>
> If it would not work, I would consider it a bug.

Indeed, having thought some more about it, I think it'll work OK.
I was thinking of cases like:

   (pcase-setq (or (and `(,a . ,b) (guard (> a b)))
                   (and (pred consp) (pred (car-less-than-car a))))
               thing)

where the value of `a' used in the pred could be affected by the
previous `a' setting for the guard, but the guard should still use
let-binding rather than setq AFAICT, so I think we're fine.

A more direct inconvenience is that `let' will be turned into a `setq':

  (pcase-setq (or (and a (pred numberp)) (let a 0)) x)

This is not too bad in the sense that it's useful behavior, but the
problem is in the clash between the name `let' used for that pattern and
the actual behavior.

>> Any chance you could directly hook this into gv.el so that we can
>> simply do (setf `(,a . ,b) ...) ?
> A far-reaching question!
> Do we really want to allow that anything accepts a generalized variable
> and a pcase pattern at the same time (your answer is obviously "yes").

Actually, no, I don't think 100% integration between the two makes much
sense: a GV is usually expected to denote a "place" where we can store
any value via side-effects whereas a pcase pattern usually denotes
a subset of possible values.

In other terms, a pcase pattern generally resembles a *constructor*, so
as to only accept values generated by this constructor and to extract
the arguments that were passed to this constructor.  IOW the pcase
takes a constructor and gives you the matching destructor.

Whereas a GV generally resembles a *destructor*, and its expander is
kind-of-like-but-not-really a way to get the matching constructor.

I don't think a generalized variable would make much sense in
a pcase statement.

But I think that the intersection of generalized-variables and pcase
patterns that can be used in pcase-setq is pretty much the empty-set
[ save for the dummy:

   ;;; Even more debatable extensions.
   (put 'cons 'gv-expander
        (lambda (do a d)
          (gv-letplace (agetter asetter) a
            (gv-letplace (dgetter dsetter) d
              (funcall do
                       `(cons ,agetter ,dgetter)
                       (lambda (v) `(progn
                                 ,(funcall asetter `(car ,v))
                                 ,(funcall dsetter `(cdr ,v)))))))))

that's in gv.el.  ]

so if doable, it would be nice to merge the pcase-setq functionality
into setf.

> in all cases?  With other words: Would it make sense that at any place
> in a pcase pattern where a symbol would be bound, an arbitrary place
> expression would be allowed, too?

Right, that'd be the natural way to mix the two: have them joined at the
place where the "select&extract" part of pcase is done and the "store
somewhere" of setf can start.

But note that it makes sense for pcase-setq since that's naturally
side-effecting but it makes much less sense for pcase-let or pcase.
For those, we'd need a `cl-letf' kind of semantics, IOW a dynamic
scoping semantics.

Also, I'm not convinced that it would be very useful.
I mean, yes, you could write

  (pcase-setq `(,(gethash k1 t) . ,(gethash k2 t)) <foo>)

but do we really want to go there?

So, yeah, maybe we're better off with a separate pcase-setq.


        Stefan



  parent reply	other threads:[~2015-10-14 15:49 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-07-08 12:20 pcase-dolist Michael Heerdegen
2015-07-08 13:54 ` pcase-dolist Stefan Monnier
2015-07-08 17:32   ` pcase-dolist Michael Heerdegen
2015-07-08 18:26     ` pcase-dolist Tassilo Horn
2015-07-08 21:27       ` pcase-dolist Stefan Monnier
2015-07-09  6:05         ` pcase-dolist Tassilo Horn
2015-07-09  9:55           ` pcase-dolist Thierry Volpiatto
2015-07-09 10:17             ` pcase-dolist Tassilo Horn
2015-07-09 12:19               ` pcase-dolist Thierry Volpiatto
2015-07-09 13:34                 ` pcase-dolist Tassilo Horn
2015-07-09 13:40                   ` pcase-dolist Thierry Volpiatto
2015-07-09 19:26           ` pcase-dolist Stefan Monnier
2015-07-09 20:27             ` pcase-dolist Michael Heerdegen
2015-07-10 18:51               ` pcase-dolist Stefan Monnier
2015-10-12 11:27               ` pcase-setq (was: pcase-dolist) Michael Heerdegen
2015-10-12 11:54                 ` pcase-setq Michael Heerdegen
2015-10-12 12:01                 ` pcase-setq (was: pcase-dolist) Nicolas Petton
2015-10-12 12:36                   ` pcase-setq Michael Heerdegen
2015-10-12 12:49                   ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Michael Heerdegen
2015-10-12 13:41                     ` Semantic of pcase `seq' and `map' patterns Michael Heerdegen
2015-10-12 13:55                       ` Nicolas Petton
2015-10-12 14:02                         ` Michael Heerdegen
2015-10-17 12:21                           ` Michael Heerdegen
2015-10-17 13:31                             ` Nicolas Petton
2015-10-12 13:50                     ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Nicolas Petton
2015-10-13  0:59                 ` pcase-setq Stefan Monnier
2015-10-13 13:52                   ` pcase-setq Michael Heerdegen
2015-10-13 14:02                     ` pcase-setq Michael Heerdegen
2015-10-13 15:52                       ` pcase-setq Michael Heerdegen
     [not found]                         ` <jwvfv1eboo8.fsf-monnier+emacs@gnu.org>
     [not found]                           ` <87d1wh36as.fsf@web.de>
2015-10-14 15:49                             ` Stefan Monnier [this message]
2015-07-10 14:44             ` pcase-dolist Tassilo Horn
2015-07-10 19:04               ` pcase-dolist Stefan Monnier
2015-07-08 19:44     ` pcase-dolist Artur Malabarba
2015-07-08 20:50       ` pcase-dolist Michael Heerdegen

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=jwvbnc1a3lf.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=emacs-devel@gnu.org \
    --cc=michael_heerdegen@web.de \
    /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).