[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: pcase-setq
From: |
Stefan Monnier |
Subject: |
Re: pcase-setq |
Date: |
Wed, 14 Oct 2015 11:49:43 -0400 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux) |
> (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
- pcase-setq (was: pcase-dolist), Michael Heerdegen, 2015/10/12
- Re: pcase-setq, Michael Heerdegen, 2015/10/12
- Re: pcase-setq, Stefan Monnier, 2015/10/12
- Re: pcase-setq, Michael Heerdegen, 2015/10/13
- Re: pcase-setq, Michael Heerdegen, 2015/10/15
- Re: pcase-setq, Michael Heerdegen, 2015/10/13
- Message not available
- Message not available
- Re: pcase-setq,
Stefan Monnier <=
Re: pcase-setq (was: pcase-dolist), Nicolas Petton, 2015/10/15
- Semantic of pcase `seq' and `map' patterns (was: pcase-setq), Michael Heerdegen, 2015/10/12
- Re: Semantic of pcase `seq' and `map' patterns, Michael Heerdegen, 2015/10/12
- Re: Semantic of pcase `seq' and `map' patterns, Nicolas Petton, 2015/10/12
- Re: Semantic of pcase `seq' and `map' patterns, Michael Heerdegen, 2015/10/12
- Re: Semantic of pcase `seq' and `map' patterns, Michael Heerdegen, 2015/10/17
- Re: Semantic of pcase `seq' and `map' patterns, Nicolas Petton, 2015/10/17
Re: Semantic of pcase `seq' and `map' patterns (was: pcase-setq), Nicolas Petton, 2015/10/15
Re: pcase-setq, Michael Heerdegen, 2015/10/15