unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* pcase-dolist
@ 2014-07-11 10:35 Sebastian Wiesner
  2014-07-11 13:47 ` pcase-dolist Stefan Monnier
  0 siblings, 1 reply; 38+ messages in thread
From: Sebastian Wiesner @ 2014-07-11 10:35 UTC (permalink / raw)
  To: emacs-devel

Hi,

I just noticed that pcase.el has a `pcase-dolist' macro, which looks quite useful.

However, unlike `pcase’ and `pcase-let’ it’s neither autoloaded nor documented, which suggests that it is somehow internal and should not be used in Emacs Lisp code.

Is this merely an oversight, or are we not supposed to use this macro in Emacs Lisp code for some reason?

Greetings,
Sebastian Wiesner


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2014-07-11 10:35 pcase-dolist Sebastian Wiesner
@ 2014-07-11 13:47 ` Stefan Monnier
  2014-07-11 13:50   ` pcase-dolist Sebastian Wiesner
  0 siblings, 1 reply; 38+ messages in thread
From: Stefan Monnier @ 2014-07-11 13:47 UTC (permalink / raw)
  To: Sebastian Wiesner; +Cc: emacs-devel

> I just noticed that pcase.el has a `pcase-dolist' macro, which looks
> quite useful.

Indeed, I like it.

> Is this merely an oversight, or are we not supposed to use this macro in
> Emacs Lisp code for some reason?

It was a lack of decision.  I do use it, and you can use it as well.
Just (require 'pcase) before doing so.

I think pcase-dolist should ultimately be renamed to just `dolist'.


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2014-07-11 13:47 ` pcase-dolist Stefan Monnier
@ 2014-07-11 13:50   ` Sebastian Wiesner
  2014-07-11 14:14     ` pcase-dolist Stefan Monnier
  0 siblings, 1 reply; 38+ messages in thread
From: Sebastian Wiesner @ 2014-07-11 13:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Is this merely an oversight, or are we not supposed to use this macro in
>> Emacs Lisp code for some reason?
> 
> It was a lack of decision.  I do use it, and you can use it as well.

And it’s not just going away at some time, is it?

> Just (require 'pcase) before doing so.

Obviously.

> I think pcase-dolist should ultimately be renamed to just `dolist'.

I’d like that, but will that happen by making a proper obsolete alias that doesn’t immediately break my code, given that pcase-dolist isn’t “advertised”?




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2014-07-11 13:50   ` pcase-dolist Sebastian Wiesner
@ 2014-07-11 14:14     ` Stefan Monnier
  0 siblings, 0 replies; 38+ messages in thread
From: Stefan Monnier @ 2014-07-11 14:14 UTC (permalink / raw)
  To: Sebastian Wiesner; +Cc: emacs-devel

> Is this merely an oversight, or are we not supposed to use this macro in
>>> Emacs Lisp code for some reason?
>> It was a lack of decision.  I do use it, and you can use it as well.
> And it’s not just going away at some time, is it?

No.

>> I think pcase-dolist should ultimately be renamed to just `dolist'.
> I’d like that, but will that happen by making a proper obsolete alias that
> doesn’t immediately break my code, given that pcase-dolist isn’t
> “advertised”?

Yes.  If/when it gets renamed to `dolist', the old name will have the
usual obsolete-alias (which, as usual will only stay there for a few
years/releases, tho).


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* pcase-dolist
@ 2015-07-08 12:20 Michael Heerdegen
  2015-07-08 13:54 ` pcase-dolist Stefan Monnier
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-07-08 12:20 UTC (permalink / raw)
  To: Emacs Development

Hello,

I was recently bitten by unexpected behavior of `pcase-dolist'.
Like `pcase-let' (which is used internally by `pcase-dolist'), AFAICT it
assumes that the pattern always matches, e.g.

(pcase-dolist ((and x (pred < 0)) '(-1 0 1 2))
  (message "%s" x))

prints all members of the sequence.

Apart from the question whether this semantic is useful: with the
current semantic, a name that includes "case" is irritating considering
such a behavior.  Maybe "pdolist" (and "plet", "plet*") would be better
names?

Anyway, an idea that came to my mind more than once: `when-let',
`if-let' should really be `pcase-when-let' , `pcase-if-let'.  They would
be much more useful than the plain versions I think.

Then `pcase-dolist' could be reimplemented using `pcase-when-let'.


Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 12:20 pcase-dolist Michael Heerdegen
@ 2015-07-08 13:54 ` Stefan Monnier
  2015-07-08 17:32   ` pcase-dolist Michael Heerdegen
  0 siblings, 1 reply; 38+ messages in thread
From: Stefan Monnier @ 2015-07-08 13:54 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: Emacs Development

> (pcase-dolist ((and x (pred < 0)) '(-1 0 1 2))
>   (message "%s" x))
> prints all members of the sequence.

What would you want it to do?

I think it'd be the only other meaningful behavior would be to signal an
error, but that would rarely be useful.

It could also skip those elements that don't match, but then it'd be
more like a "filter" loop so it would need another name.  And it would
then be very tempting/desirable to make it possible to provide a chunk
of code to use when the pattern doesn't match.  So we'd end up with
something like

   (pcase-newdolist LIST
    (PAT1 . BODY1)
    (PAT2 . BODY2)
    ...)

which would just be a shorthand for

   (dolist (x LIST)
     (pcase x
       (PAT1 . BODY1)
       (PAT2 . BODY2)
       ...))

> Apart from the question whether this semantic is useful: with the
> current semantic, a name that includes "case" is irritating considering
> such a behavior.

I completely read the name as "<prefix>-dolist" but you have a good
point: the prefix has "case" in its name, which makes it misleading.

> Maybe "pdolist" (and "plet", "plet*") would be better names?

For pcase-dolist, I think the right name to use is `dolist'.

> Anyway, an idea that came to my mind more than once: `when-let',
> `if-let' should really be `pcase-when-let' , `pcase-if-let'.  They would
> be much more useful than the plain versions I think.

Yes, feel free to change them that way.

> Then `pcase-dolist' could be reimplemented using `pcase-when-let'.

Not sure what you mean: the current semantics of pcase-dolist is the
right one IMNSHO.


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 13:54 ` pcase-dolist Stefan Monnier
@ 2015-07-08 17:32   ` Michael Heerdegen
  2015-07-08 18:26     ` pcase-dolist Tassilo Horn
  2015-07-08 19:44     ` pcase-dolist Artur Malabarba
  0 siblings, 2 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-07-08 17:32 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> It could also skip those elements that don't match

That's what I had expected without thinking too much about it.  But I
agree that we would end with something different.

> For pcase-dolist, I think the right name to use is `dolist'.

Sounds good!

> > Anyway, an idea that came to my mind more than once: `when-let',
> > `if-let' should really be `pcase-when-let' , `pcase-if-let'.  They
> > would be much more useful than the plain versions I think.
>
> Yes, feel free to change them that way.

Though, just changing them would break existing code (the current
versions are about boolean values, the pcase versions would be about
pattern matching).

For example, now

  (if-let ((a (ignore))) a 17)       ==> 17,

but

  (pcase-if-let ((a (ignore))) a 17) ==> nil.


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 17:32   ` pcase-dolist Michael Heerdegen
@ 2015-07-08 18:26     ` Tassilo Horn
  2015-07-08 21:27       ` pcase-dolist Stefan Monnier
  2015-07-08 19:44     ` pcase-dolist Artur Malabarba
  1 sibling, 1 reply; 38+ messages in thread
From: Tassilo Horn @ 2015-07-08 18:26 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

>> It could also skip those elements that don't match
>
> That's what I had expected without thinking too much about it.  But I
> agree that we would end with something different.

I also think that `pcase-let' and `pcase-dolist' are pretty confusing.
For example,

  (pcase-let ((`(,w ,x ,y ,z) '(1 2 3)))
    (message "%s %s %s %s" w x y z))

prints "1 2 3 nil" although the pattern when used in `pcase' wouldn't
match that list but only 4-element lists.  So a pcase pattern has
different semantics depending on whether it is used in `pcase' or
`pcase-let' or `pcase-dolist' which doesn't feel right.

I'd prefer if `pcase-let' would signal an error if some pattern doesn't
match.  Same for `pcase-dolist' with its current semantics.  IMHO, the
code above clearly says that the programmer expected to destructure
4-element lists so an error signaling that the expectation is wrong
sounds right.

>> > Anyway, an idea that came to my mind more than once: `when-let',
>> > `if-let' should really be `pcase-when-let' , `pcase-if-let'.  They
>> > would be much more useful than the plain versions I think.
>>
>> Yes, feel free to change them that way.
>
> Though, just changing them would break existing code (the current
> versions are about boolean values, the pcase versions would be about
> pattern matching).

So why not have both?

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 17:32   ` pcase-dolist Michael Heerdegen
  2015-07-08 18:26     ` pcase-dolist Tassilo Horn
@ 2015-07-08 19:44     ` Artur Malabarba
  2015-07-08 20:50       ` pcase-dolist Michael Heerdegen
  1 sibling, 1 reply; 38+ messages in thread
From: Artur Malabarba @ 2015-07-08 19:44 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

>> > Anyway, an idea that came to my mind more than once: `when-let',
>> > `if-let' should really be `pcase-when-let' , `pcase-if-let'.  They
>> > would be much more useful than the plain versions I think.
>>
>> Yes, feel free to change them that way.
>
> Though, just changing them would break existing code (the current
> versions are about boolean values, the pcase versions would be about
> pattern matching).
>
> For example, now
>
>   (if-let ((a (ignore))) a 17)       ==> 17,
>
> but
>
>   (pcase-if-let ((a (ignore))) a 17) ==> nil.

Only if you make them like this. The idea of `(if-let ((a expr))
body)' is that evaluate `expr' and, if it is non-nil, bind it to a and
run `body'. This doesn't exclude the possibility of `a' being a pcase
pattern. Just make sure that the the check for nil expr is done as a
separate thing, before the pattern matching.

If you implement pcase-if-let the way you suggest above, isn't that
just the same as pcase?



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 19:44     ` pcase-dolist Artur Malabarba
@ 2015-07-08 20:50       ` Michael Heerdegen
  0 siblings, 0 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-07-08 20:50 UTC (permalink / raw)
  To: emacs-devel

Artur Malabarba <bruce.connor.am@gmail.com> writes:

> Only if you make them like this. The idea of `(if-let ((a expr))
> body)' is that evaluate `expr' and, if it is non-nil, bind it to a and
> run `body'. This doesn't exclude the possibility of `a' being a pcase
> pattern. Just make sure that the the check for nil expr is done as a
> separate thing, before the pattern matching.

I don't know if I would like that semantic.  It doesn't sound intuitive
to me.

> If you implement pcase-if-let the way you suggest above, isn't that
> just the same as pcase?

For one binding, yes.  The body would be at a more prominent place
though.

Isn't if-let not just pcase as well?

  (if-let ((var expr)) then else)

  (pcase expr ((and var (guard var)) then) (_ else))


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 18:26     ` pcase-dolist Tassilo Horn
@ 2015-07-08 21:27       ` Stefan Monnier
  2015-07-09  6:05         ` pcase-dolist Tassilo Horn
  0 siblings, 1 reply; 38+ messages in thread
From: Stefan Monnier @ 2015-07-08 21:27 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

>   (pcase-let ((`(,w ,x ,y ,z) '(1 2 3)))
>     (message "%s %s %s %s" w x y z))

> prints "1 2 3 nil" although the pattern when used in `pcase' wouldn't
> match that list but only 4-element lists.  So a pcase pattern has
> different semantics depending on whether it is used in `pcase' or
> `pcase-let' or `pcase-dolist' which doesn't feel right.

> I'd prefer if `pcase-let' would signal an error if some pattern doesn't
> match.

So you'd want the above to signal an error in the case of:

   (pcase-let ((`(,w ,x) '(1 2 3)))
     (message "%s %s" w x))

?


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-08 21:27       ` pcase-dolist Stefan Monnier
@ 2015-07-09  6:05         ` Tassilo Horn
  2015-07-09  9:55           ` pcase-dolist Thierry Volpiatto
  2015-07-09 19:26           ` pcase-dolist Stefan Monnier
  0 siblings, 2 replies; 38+ messages in thread
From: Tassilo Horn @ 2015-07-09  6:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Michael Heerdegen, emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>>   (pcase-let ((`(,w ,x ,y ,z) '(1 2 3)))
>>     (message "%s %s %s %s" w x y z))
>
>> prints "1 2 3 nil" although the pattern when used in `pcase' wouldn't
>> match that list but only 4-element lists.  So a pcase pattern has
>> different semantics depending on whether it is used in `pcase' or
>> `pcase-let' or `pcase-dolist' which doesn't feel right.
>
>> I'd prefer if `pcase-let' would signal an error if some pattern doesn't
>> match.
>
> So you'd want the above to signal an error in the case of:
>
>    (pcase-let ((`(,w ,x) '(1 2 3)))
>      (message "%s %s" w x))
>
> ?

Yes, if you want to pick the first two elements of a list with 2 or more
elements, you should use `(,w ,x . ,_).  I see that the above is
slightly more convenient and concise but I'd value consistency more.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09  6:05         ` pcase-dolist Tassilo Horn
@ 2015-07-09  9:55           ` Thierry Volpiatto
  2015-07-09 10:17             ` pcase-dolist Tassilo Horn
  2015-07-09 19:26           ` pcase-dolist Stefan Monnier
  1 sibling, 1 reply; 38+ messages in thread
From: Thierry Volpiatto @ 2015-07-09  9:55 UTC (permalink / raw)
  To: emacs-devel

Tassilo Horn <tsdh@gnu.org> writes:

> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>>   (pcase-let ((`(,w ,x ,y ,z) '(1 2 3)))
>>>     (message "%s %s %s %s" w x y z))
>>
>>> prints "1 2 3 nil" although the pattern when used in `pcase' wouldn't
>>> match that list but only 4-element lists.  So a pcase pattern has
>>> different semantics depending on whether it is used in `pcase' or
>>> `pcase-let' or `pcase-dolist' which doesn't feel right.
>>
>>> I'd prefer if `pcase-let' would signal an error if some pattern doesn't
>>> match.
>>
>> So you'd want the above to signal an error in the case of:
>>
>>    (pcase-let ((`(,w ,x) '(1 2 3)))
>>      (message "%s %s" w x))
>>
>> ?
>
> Yes, if you want to pick the first two elements of a list with 2 or more
> elements, you should use `(,w ,x . ,_).  I see that the above is
> slightly more convenient and concise but I'd value consistency more.

This would be a regression IMHO, what if you want to do e.g:

(pcase-let ((`(,a ,b) (file-attributes "foo")))
  (list a b))

It would be inconvenient to have to bind the 10 unused remaining elements.

Of course one can use `cl-multiple-value-bind' instead in such situation.

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09  9:55           ` pcase-dolist Thierry Volpiatto
@ 2015-07-09 10:17             ` Tassilo Horn
  2015-07-09 12:19               ` pcase-dolist Thierry Volpiatto
  0 siblings, 1 reply; 38+ messages in thread
From: Tassilo Horn @ 2015-07-09 10:17 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: emacs-devel

Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:

>>> So you'd want the above to signal an error in the case of:
>>>
>>>    (pcase-let ((`(,w ,x) '(1 2 3)))
>>>      (message "%s %s" w x))
>>>
>>> ?
>>
>> Yes, if you want to pick the first two elements of a list with 2 or
>> more elements, you should use `(,w ,x . ,_).  I see that the above is
>> slightly more convenient and concise but I'd value consistency more.
>
> This would be a regression IMHO, what if you want to do e.g:
>
> (pcase-let ((`(,a ,b) (file-attributes "foo")))
>   (list a b))
>
> It would be inconvenient to have to bind the 10 unused remaining
> elements.

As I've said, you can use cdr-matching with a don't-care-pattern, e.g.,

  (pcase-let ((`(,a ,b . ,_) (file-attributes "~/.emacs")))
    (list a b))

which clearly states that you know that the list returned by
`file-attributes' has more than two elements but you are only interested
in the first two.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 10:17             ` pcase-dolist Tassilo Horn
@ 2015-07-09 12:19               ` Thierry Volpiatto
  2015-07-09 13:34                 ` pcase-dolist Tassilo Horn
  0 siblings, 1 reply; 38+ messages in thread
From: Thierry Volpiatto @ 2015-07-09 12:19 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel


Tassilo Horn <tsdh@gnu.org> writes:

> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
>
>>>> So you'd want the above to signal an error in the case of:
>>>>
>>>>    (pcase-let ((`(,w ,x) '(1 2 3)))
>>>>      (message "%s %s" w x))
>>>>
>>>> ?
>>>
>>> Yes, if you want to pick the first two elements of a list with 2 or
>>> more elements, you should use `(,w ,x . ,_).  I see that the above is
>>> slightly more convenient and concise but I'd value consistency more.
>>
>> This would be a regression IMHO, what if you want to do e.g:
>>
>> (pcase-let ((`(,a ,b) (file-attributes "foo")))
>>   (list a b))
>>
>> It would be inconvenient to have to bind the 10 unused remaining
>> elements.
>
> As I've said, you can use cdr-matching with a don't-care-pattern, e.g.,
>
>   (pcase-let ((`(,a ,b . ,_) (file-attributes "~/.emacs")))
>     (list a b))
>
> which clearly states that you know that the list returned by
> `file-attributes' has more than two elements but you are only interested
> in the first two.

Ah! Ok so the dont-care-pattern handle all the remaining elements.
So yes like this the intention is clearer.

Thanks.

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 12:19               ` pcase-dolist Thierry Volpiatto
@ 2015-07-09 13:34                 ` Tassilo Horn
  2015-07-09 13:40                   ` pcase-dolist Thierry Volpiatto
  0 siblings, 1 reply; 38+ messages in thread
From: Tassilo Horn @ 2015-07-09 13:34 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: emacs-devel

Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:

>> As I've said, you can use cdr-matching with a don't-care-pattern,
>> e.g.,
>>
>>   (pcase-let ((`(,a ,b . ,_) (file-attributes "~/.emacs")))
>>     (list a b))
>>
>> which clearly states that you know that the list returned by
>> `file-attributes' has more than two elements but you are only interested
>> in the first two.
>
> Ah! Ok so the dont-care-pattern handle all the remaining elements.

No, the crucial part is the dot separating the front from the rest of
the list.  With `(,a ,b . ,r) the list of the 8 remaining file
attributes would be bound to r.  When you don't need those, you can omit
the binding with the don't care pattern.

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 13:34                 ` pcase-dolist Tassilo Horn
@ 2015-07-09 13:40                   ` Thierry Volpiatto
  0 siblings, 0 replies; 38+ messages in thread
From: Thierry Volpiatto @ 2015-07-09 13:40 UTC (permalink / raw)
  To: Tassilo Horn; +Cc: emacs-devel


Tassilo Horn <tsdh@gnu.org> writes:

> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
>
>>> As I've said, you can use cdr-matching with a don't-care-pattern,
>>> e.g.,
>>>
>>>   (pcase-let ((`(,a ,b . ,_) (file-attributes "~/.emacs")))
>>>     (list a b))
>>>
>>> which clearly states that you know that the list returned by
>>> `file-attributes' has more than two elements but you are only interested
>>> in the first two.
>>
>> Ah! Ok so the dont-care-pattern handle all the remaining elements.
>
> No, the crucial part is the dot separating the front from the rest of
> the list.  With `(,a ,b . ,r) the list of the 8 remaining file
> attributes would be bound to r.  When you don't need those, you can omit
> the binding with the don't care pattern.

Yes it's what I understood.

Thanks.

-- 
Thierry
Get my Gnupg key:
gpg --keyserver pgp.mit.edu --recv-keys 59F29997 



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09  6:05         ` pcase-dolist Tassilo Horn
  2015-07-09  9:55           ` pcase-dolist Thierry Volpiatto
@ 2015-07-09 19:26           ` Stefan Monnier
  2015-07-09 20:27             ` pcase-dolist Michael Heerdegen
  2015-07-10 14:44             ` pcase-dolist Tassilo Horn
  1 sibling, 2 replies; 38+ messages in thread
From: Stefan Monnier @ 2015-07-09 19:26 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> Yes, if you want to pick the first two elements of a list with 2 or more
> elements, you should use `(,w ,x . ,_).  I see that the above is
> slightly more convenient and concise but I'd value consistency more.

But that does not match the usual uses of "tuples represented as lists",
where it's customary to use (A B) when the remaining fields are all nil
(since (car nil) returns nil and (nth 5 '(1 2)) also returns nil rather
than signaling an error) and where it's also customary to ignore any
additional element.

IOW maybe your approach seems more consistent, but not only does it
generate less efficient code, but it also requires extra source code in
the usual cases.


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 19:26           ` pcase-dolist Stefan Monnier
@ 2015-07-09 20:27             ` Michael Heerdegen
  2015-07-10 18:51               ` pcase-dolist Stefan Monnier
  2015-10-12 11:27               ` pcase-setq (was: pcase-dolist) Michael Heerdegen
  2015-07-10 14:44             ` pcase-dolist Tassilo Horn
  1 sibling, 2 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-07-09 20:27 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

> But that does not match the usual uses of "tuples represented as
> lists", where it's customary to use (A B) when the remaining fields
> are all nil (since (car nil) returns nil and (nth 5 '(1 2)) also
> returns nil rather than signaling an error) and where it's also
> customary to ignore any additional element.

Good argument.  OTOH, if you _want_ to distinguish e.g. a two from a
three element list, you will have to use something like `(,a ,b . ,r)
and test whether r is nil.  Mmh.  Anyway, pcase and pcase-let should
at least behave the same at the end I think...


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 19:26           ` pcase-dolist Stefan Monnier
  2015-07-09 20:27             ` pcase-dolist Michael Heerdegen
@ 2015-07-10 14:44             ` Tassilo Horn
  2015-07-10 19:04               ` pcase-dolist Stefan Monnier
  1 sibling, 1 reply; 38+ messages in thread
From: Tassilo Horn @ 2015-07-10 14:44 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Michael Heerdegen, emacs-devel

Stefan Monnier <monnier@IRO.UMontreal.CA> writes:

>> Yes, if you want to pick the first two elements of a list with 2 or
>> more elements, you should use `(,w ,x . ,_).  I see that the above is
>> slightly more convenient and concise but I'd value consistency more.
>
> But that does not match the usual uses of "tuples represented as
> lists", where it's customary to use (A B) when the remaining fields
> are all nil (since (car nil) returns nil and (nth 5 '(1 2)) also
> returns nil rather than signaling an error) and where it's also
> customary to ignore any additional element.

Yes, but those don't have pcase in their name.  If that wouldn't be the
case with `pcase-let' I would not complain at all.

Hm, when you said that a better name for `pcase-dolist' was `dolist',
wouldn't `let(*)' be a better name for `pcase-let(*)', too?  It would be
very useful to be able to destructure in usual lets (like, e.g., in
Clojure).  I think there are gazillion of occurrences of

  (let* ((this-and-that (foo ...))
         (this (car this-and-that))
         (that (cdr this-and-that)))
    ...)

AFAICS, the only thing that `pcase-let' is lacking is the ability to
introduce locals without providing a value, e.g.,

  (let ((x 1) b c) ...)

but that shouldn't be too hard to add, no?

Bye,
Tassilo



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-09 20:27             ` pcase-dolist Michael Heerdegen
@ 2015-07-10 18:51               ` Stefan Monnier
  2015-10-12 11:27               ` pcase-setq (was: pcase-dolist) Michael Heerdegen
  1 sibling, 0 replies; 38+ messages in thread
From: Stefan Monnier @ 2015-07-10 18:51 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> Good argument.  OTOH, if you _want_ to distinguish e.g. a two from a
> three element list, you will have to use something like `(,a ,b . ,r)
> and test whether r is nil.

No: pcase-let is for "destructuring", not for "distinguishing".
IOW if you want "to distinguish e.g. a two from a three element list"
you want to use `pcase'.

> Mmh.  Anyway, pcase and pcase-let should
> at least behave the same at the end I think...

Then what would be the benefit of having `pcase-let'?


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-dolist
  2015-07-10 14:44             ` pcase-dolist Tassilo Horn
@ 2015-07-10 19:04               ` Stefan Monnier
  0 siblings, 0 replies; 38+ messages in thread
From: Stefan Monnier @ 2015-07-10 19:04 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> Yes, but those don't have pcase in their name.

As mentioned earlier, I agree that the name is misleading (and it didn't
occur to me, because to me "pcase-" is just a prefix) this name is only
used because pcase-let uses the same pattern syntax and underlying
machinery as `pcase'.  We could rename it to `plet' (or even to just
`let').

> Hm, when you said that a better name for `pcase-dolist' was `dolist',
> wouldn't `let(*)' be a better name for `pcase-let(*)', too?

Yes.  2 reasons why it's not done:
- just as for dolist, I haven't made that jump (yet?), it's one of those
  things where there's no going back, so I need to work up my courage
  and convince myself it's worthwhile.
- since `let' is currently a builtin element, and used in the expansion
  of pcase-let, there are some technical details that'd need to be
  resolved (the technical issues for dolist are trivial in comparison).

> It would be very useful to be able to destructure in usual lets (like,
> e.g., in Clojure).

That's why I introduced pcase-let.

> AFAICS, the only thing that `pcase-let' is lacking is the ability to
> introduce locals without providing a value, e.g.,
>   (let ((x 1) b c) ...)

I tend to dislike these things, so I intentionally didn't add support
for them in pcase-let, but it'd be trivial to support them.


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* pcase-setq (was: pcase-dolist)
  2015-07-09 20:27             ` pcase-dolist Michael Heerdegen
  2015-07-10 18:51               ` pcase-dolist Stefan Monnier
@ 2015-10-12 11:27               ` Michael Heerdegen
  2015-10-12 11:54                 ` pcase-setq Michael Heerdegen
                                   ` (2 more replies)
  1 sibling, 3 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 11:27 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stefan Monnier

Hello,  (@Stefan I hope you don't mind I CC'd you the second time today)

I think a useful addition could be `pcase-setq' as an alternative to
`destructuring-bind'.

AFAIU it should not be hard to implement it - similarly to `pcase--let*'
I guess.

Opinions?


Regards,

Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  2015-10-12 11:27               ` pcase-setq (was: pcase-dolist) Michael Heerdegen
@ 2015-10-12 11:54                 ` Michael Heerdegen
  2015-10-12 12:01                 ` pcase-setq (was: pcase-dolist) Nicolas Petton
  2015-10-13  0:59                 ` pcase-setq Stefan Monnier
  2 siblings, 0 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 11:54 UTC (permalink / raw)
  To: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> I think a useful addition could be `pcase-setq' as an alternative to
> `destructuring-bind'.

Thinko: a bad comparison; `destructuring-bind' is not a "setter", I must
have mistaken it for something different.  But I think it's clear what
the semantic of `pcase-setq' would be.


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq (was: pcase-dolist)
  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                 ` 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-13  0:59                 ` pcase-setq Stefan Monnier
  2 siblings, 2 replies; 38+ messages in thread
From: Nicolas Petton @ 2015-10-12 12:01 UTC (permalink / raw)
  To: Michael Heerdegen, emacs-devel; +Cc: Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 560 bytes --]

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Hello,  (@Stefan I hope you don't mind I CC'd you the second time today)
>
> I think a useful addition could be `pcase-setq' as an alternative to
> `destructuring-bind'.

I don't know if it that's what you are looking for, but seq.el has
`seq-let` and map.el has `map-let`, and they both use pcase.

    (seq-let (a b (c &rest others)) '(1 2 [3 4 5 6])
      (+ a b c))

    (map-let (foo bar baz) '((foo . 1) (bar . 2))
      (should (= foo 1))
      (should (= bar 2))
      (should (null baz)))

Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  2015-10-12 12:01                 ` pcase-setq (was: pcase-dolist) Nicolas Petton
@ 2015-10-12 12:36                   ` Michael Heerdegen
  2015-10-12 12:49                   ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Michael Heerdegen
  1 sibling, 0 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 12:36 UTC (permalink / raw)
  To: emacs-devel

Nicolas Petton <nicolas@petton.fr> writes:

> I don't know if it that's what you are looking for, but seq.el has
> `seq-let` and map.el has `map-let`, and they both use pcase.
>
>     (seq-let (a b (c &rest others)) '(1 2 [3 4 5 6])
>       (+ a b c))
>
>     (map-let (foo bar baz) '((foo . 1) (bar . 2))
>       (should (= foo 1))
>       (should (= bar 2))
>       (should (null baz)))

What I want is a _setter_ macro using pcase, not a binding construct
(sorry, I was confused about what `cl-destructuring-bind' does).

Like this:

(pcase-setq (seq a b (seq c)) '(1 2 [3 4 5 6]))
(+ a b c)  ==> 6


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Semantic of pcase `seq' and `map' patterns (was: pcase-setq)
  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                   ` Michael Heerdegen
  2015-10-12 13:41                     ` Semantic of pcase `seq' and `map' patterns Michael Heerdegen
  2015-10-12 13:50                     ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Nicolas Petton
  1 sibling, 2 replies; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 12:49 UTC (permalink / raw)
  To: emacs-devel

Nicolas Petton <nicolas@petton.fr> writes:

>     (seq-let (a b (c &rest others)) '(1 2 [3 4 5 6])
>       (+ a b c))

After reading the doc of the `seq' pcase pattern:

--8<---------------cut here---------------start------------->8---
-- (seq &rest ARGS)

pcase pattern matching sequence elements.
Matches if the object is a sequence (list, string or vector), and
binds each element of ARGS to the corresponding element of the
sequence.
--8<---------------cut here---------------end--------------->8---

it was not obvious to me how this example would look like using pcase -
especially, what "are" the "ARGS"?

AFAIU the "ARGS" are just normal (pcase) patterns - they are not limited
to variables, and matching can fail for them as well even if the number
of sequence arguments would match.

I think the semantic would be better described like this:

--8<---------------cut here---------------start------------->8---
-- (seq &rest PATTERNS)

pcase pattern matching sequence elements.
Matches if the object is a sequence (list, string or vector), and
each PATTERN matches the corresponding element of the
sequence.
--8<---------------cut here---------------end--------------->8---

Does that make sense?  Likewise `map', I guess.


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns
  2015-10-12 12:49                   ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Michael Heerdegen
@ 2015-10-12 13:41                     ` Michael Heerdegen
  2015-10-12 13:55                       ` Nicolas Petton
  2015-10-12 13:50                     ` Semantic of pcase `seq' and `map' patterns (was: pcase-setq) Nicolas Petton
  1 sibling, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 13:41 UTC (permalink / raw)
  To: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> -- (seq &rest PATTERNS)
>
> pcase pattern matching sequence elements.
> Matches if the object is a sequence (list, string or vector), and
> each PATTERN matches the corresponding element of the
> sequence.

It should probably also say that supernumerary elements of the object
sequence are ignored if less PATTERNS are given, and the match doesn't
fail.

BTW, if I want to match [1 2 3 4] and bind a to 1 and b to (2 3 4), is
this possible using the `seq' pattern?


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns (was: pcase-setq)
  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:50                     ` Nicolas Petton
  1 sibling, 0 replies; 38+ messages in thread
From: Nicolas Petton @ 2015-10-12 13:50 UTC (permalink / raw)
  To: Michael Heerdegen, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1398 bytes --]

Michael Heerdegen <michael_heerdegen@web.de> writes:

> After reading the doc of the `seq' pcase pattern:
>
> --8<---------------cut here---------------start------------->8---
> -- (seq &rest ARGS)
>
> pcase pattern matching sequence elements.
> Matches if the object is a sequence (list, string or vector), and
> binds each element of ARGS to the corresponding element of the
> sequence.
> --8<---------------cut here---------------end--------------->8---
>
> it was not obvious to me how this example would look like using pcase -
> especially, what "are" the "ARGS"?
>
> AFAIU the "ARGS" are just normal (pcase) patterns - they are not limited
> to variables, and matching can fail for them as well even if the number
> of sequence arguments would match.
>
> I think the semantic would be better described like this:
>
> --8<---------------cut here---------------start------------->8---
> -- (seq &rest PATTERNS)
>
> pcase pattern matching sequence elements.
> Matches if the object is a sequence (list, string or vector), and
> each PATTERN matches the corresponding element of the
> sequence.
> --8<---------------cut here---------------end--------------->8---
>
> Does that make sense?  Likewise `map', I guess.

Yes, it does. You could for example do:

    (pcase [1 2 3 4]
      ...
      ((seq (pred oddp) (pred evenp)) 'matched)
      ...)

I will update the documentation, thanks!

Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns
  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
  0 siblings, 1 reply; 38+ messages in thread
From: Nicolas Petton @ 2015-10-12 13:55 UTC (permalink / raw)
  To: Michael Heerdegen, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 603 bytes --]

Michael Heerdegen <michael_heerdegen@web.de> writes:

> It should probably also say that supernumerary elements of the object
> sequence are ignored if less PATTERNS are given, and the match doesn't
> fail.

Yes.

>
> BTW, if I want to match [1 2 3 4] and bind a to 1 and b to (2 3 4), is
> this possible using the `seq' pattern?

Sure, using "&rest":

    (seq-let (a &rest b) [1 2 3 4]
      (format "The first is %s and the rest is %s" a b))


You can also ignore elements:

    (seq-let (a _ &rest b) [1 2 3 4]
      (format "The first is %s and the rest without the second is %s" a
      b))

Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns
  2015-10-12 13:55                       ` Nicolas Petton
@ 2015-10-12 14:02                         ` Michael Heerdegen
  2015-10-17 12:21                           ` Michael Heerdegen
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-12 14:02 UTC (permalink / raw)
  To: Nicolas Petton; +Cc: emacs-devel

Nicolas Petton <nicolas@petton.fr> writes:

> Sure, using "&rest":

And that's working with the pcase pattern, too:

(pcase '(1 2 3 4)
  ((seq a b &rest c) (list a b c)))

==> (1 2 (3 4))

So that's missing in the doc of the pcase pattern, too, since it's not
an obvious thing.

Anyway, great stuff.


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  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-13  0:59                 ` Stefan Monnier
  2015-10-13 13:52                   ` pcase-setq Michael Heerdegen
  2 siblings, 1 reply; 38+ messages in thread
From: Stefan Monnier @ 2015-10-13  0:59 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> Hello,  (@Stefan I hope you don't mind I CC'd you the second time today)
> I think a useful addition could be `pcase-setq' as an alternative to
> `destructuring-bind'.

I'm not sure I understand: "an alternative to destructuring-bind"
sounds like what pcase-let provides.

`pcase-setq' would be more like merging pcase and setf.

> AFAIU it should not be hard to implement it - similarly to `pcase--let*'
> I guess.

I don't think it's easy, actually.  But yes, that would be a useful addition.


        Stefan



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  2015-10-13  0:59                 ` pcase-setq Stefan Monnier
@ 2015-10-13 13:52                   ` Michael Heerdegen
  2015-10-13 14:02                     ` pcase-setq Michael Heerdegen
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-13 13:52 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> I'm not sure I understand: "an alternative to destructuring-bind"
> sounds like what pcase-let provides.

I was confused about `destructuring-bind', sorry.

> `pcase-setq' would be more like merging pcase and setf.

Yes, or at least `pcase' and `setq'.  Being able to set/bind generalized
variables is an orthogonal, but also interesting thing.

> I don't think it's easy, actually.  But yes, that would be a useful
> addition.

Being very naive and not yet understanding all of your code, I guess it
could be as easy as to modify/reuse the `pcase--expand' code and make
the return value that is now

    (macroexp-let* defs main)

discard main and turn the defs into a sequential `setq' form, and return
that.  Plus hashing via `pcase--memoize'.


Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  2015-10-13 13:52                   ` pcase-setq Michael Heerdegen
@ 2015-10-13 14:02                     ` Michael Heerdegen
  2015-10-13 15:52                       ` pcase-setq Michael Heerdegen
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-13 14:02 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> discard main and turn the defs into a sequential `setq' form, and return
> that.  Plus hashing via `pcase--memoize'.

No, that's a bit to easy.  But I think after having read and understood
the `pcase--expand' definition, I should be able to give it a try.


Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
  2015-10-13 14:02                     ` pcase-setq Michael Heerdegen
@ 2015-10-13 15:52                       ` Michael Heerdegen
       [not found]                         ` <jwvfv1eboo8.fsf-monnier+emacs@gnu.org>
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-13 15:52 UTC (permalink / raw)
  To: emacs-devel; +Cc: Stefan Monnier

Hello Stefan,

Here is my first attempt, ignoring all optimizations:

--8<---------------cut here---------------start------------->8---
(defmacro pcase-setq (pattern exp)
  (pcase--u
   `((,(pcase--match exp (pcase--macroexpand pattern))
      ,(lambda (vars) `(progn ,@(mapcar (lambda (b) `(setq ,(car b) ,(cdr b)))
                                   vars)))))))
--8<---------------cut here---------------end--------------->8---

Does that make sense?


Michael.




^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: pcase-setq
       [not found]                           ` <87d1wh36as.fsf@web.de>
@ 2015-10-14 15:49                             ` Stefan Monnier
  0 siblings, 0 replies; 38+ messages in thread
From: Stefan Monnier @ 2015-10-14 15:49 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

> (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



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns
  2015-10-12 14:02                         ` Michael Heerdegen
@ 2015-10-17 12:21                           ` Michael Heerdegen
  2015-10-17 13:31                             ` Nicolas Petton
  0 siblings, 1 reply; 38+ messages in thread
From: Michael Heerdegen @ 2015-10-17 12:21 UTC (permalink / raw)
  To: Nicolas Petton; +Cc: emacs-devel

Michael Heerdegen <michael_heerdegen@web.de> writes:

> > Sure, using "&rest":
>
> So that's missing in the doc of the pcase pattern, too, since it's not
> an obvious thing.

Thanks for the fixes.  But isn't the "&rest" part still missing?

And now, the second sentence for the docstring of the `map' pcase
pattern says:

"Matches if the object is a map (list, hash-table or array), and
each PATTERN matches the corresponding elements of the map."

where PATTERN is unclear for what it stands.  Of course, you can derive
it from the context if you think about it, but that should not be
necessary.

Sorry for being obtrusive.  Maybe your changes were not final so far,
sorry then.  It's just that the docstrings of the `pcase-defmacro'
defined stuff are prominently displayed in the help buffer for `pcase',
and lots of people have trouble understanding the complex pcase
semantic.  It shoul be our goal to make the pcase docstring as
unambiguous and fluent to read as possible.


Thanks,

Michael.



^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: Semantic of pcase `seq' and `map' patterns
  2015-10-17 12:21                           ` Michael Heerdegen
@ 2015-10-17 13:31                             ` Nicolas Petton
  0 siblings, 0 replies; 38+ messages in thread
From: Nicolas Petton @ 2015-10-17 13:31 UTC (permalink / raw)
  To: Michael Heerdegen; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 990 bytes --]

Michael Heerdegen <michael_heerdegen@web.de> writes:

> Michael Heerdegen <michael_heerdegen@web.de> writes:
>
>> > Sure, using "&rest":
>>
>> So that's missing in the doc of the pcase pattern, too, since it's not
>> an obvious thing.
>
> Thanks for the fixes.  But isn't the "&rest" part still missing?

Yes, it is, but my changes were not final.  We went through some more
iterations with Eli, and I will commit more improvements to docstrings
in both seq and map ASAP.

> And now, the second sentence for the docstring of the `map' pcase
> pattern says:
>
> "Matches if the object is a map (list, hash-table or array), and
> each PATTERN matches the corresponding elements of the map."
>
> where PATTERN is unclear for what it stands.  Of course, you can derive
> it from the context if you think about it, but that should not be
> necessary.
>
> Sorry for being obtrusive.

Don't be sorry, feedback is always welcome, especially went given with
good intentions, as you are doing.

Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2015-10-17 13:31 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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                             ` pcase-setq Stefan Monnier
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
  -- strict thread matches above, loose matches on Subject: below --
2014-07-11 10:35 pcase-dolist Sebastian Wiesner
2014-07-11 13:47 ` pcase-dolist Stefan Monnier
2014-07-11 13:50   ` pcase-dolist Sebastian Wiesner
2014-07-11 14:14     ` pcase-dolist Stefan Monnier

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).