* cond* vs pcase
@ 2024-02-05 14:30 Arthur Miller
2024-02-05 15:13 ` Eli Zaretskii
2024-02-05 16:06 ` Alfred M. Szmidt
0 siblings, 2 replies; 46+ messages in thread
From: Arthur Miller @ 2024-02-05 14:30 UTC (permalink / raw)
To: emacs-devel
After skimming through the toms of the emacs-devel, here is what I got:
RMS does not like pcase; it is hard to understand and under-documented, which is
actually true, at least for the latter. To remedy, you are re-invent the idea
with a different syntax.
I have been hanging on /r/Emacs for a few years now, and here is my prediction
of a future hypothetical Emacs Lisp learner asking on /r/Emacs:
"Which should I use? Pcase or cond*? Which one do you recommend?"
And hypotetical future answers:
*Toms of similar discussions similar to the one on this mailing list going on
for days, but in Reddit comments, suggestions in different directions, and more
confusion.*
To start with, I think none on this mailing list has asked this question
yet (or have I missed it?): why does it have to be a single form that does all
of the pattern stuff?
I use pcase often; but I use it just as a better cond. For example I find this
handy:
(defvar foo nil) <-- foo is some symbol
(pcase foo
('bar (do-some-bar-stuff))
('baz (do-some-baz-fluff)))
or this:
(setq foo "some-string")
(pcase foo
("foo" (do-foo-case))
("bar" (do-bar-case)))
I don't use much of pred stuff and other advancements. I probably never will;
there are other ways to structure the code. Not everything has to be done by one
and the same form, but if someone else does, power to them, I have nothing
against it.
For the same reason I also use cl-loop very sparingly (I almost never feel need
to reach for it in my own code). I think "while", "dotimes" and "dolist" tells
me much better the intention of my loop and what I wanted to do, than looking at
cl-loop and deciphering if it is a while-loop, an iteration through a collection
or a repeat loop. For the same reason, in Common Lisp, I don't try to write the
entire programs with Common Lisp format directives, nor do I try to write entire
programs with a single regular expression as some people seems to prefer. That
makes code ugly and difficult to read; I prefer to structure the code with
simpler Lisp statements.
Why this obsession that we have to have one form, be it pcase or cond*, that
covers all cases of pattern usage in conditions?
My second objection is, as many other stated here; if pcase is that hard,
resource heavy, and underdocumented, have you considred working to fix problems
and on the documentation of pcase, perhaps with Stefan?
Is it possible to simplify pcase in some places? You could have maybe worked on
pcase to make it easier to use?
Could pcase be refactored so that parts of it are loaded into the core and used
in Emacs core, and some constructs are made available only after user requires
an extra library?
If it is too resource demanding and macro expansions are a problem, is it
possible to perhaps pre-load parts of pcase implemented in only primitives
exported from the C runtime?
Instead of working together with Stefan to make pcase and Emacs Lisp a better
and easier language to use and learn, cond* is pushing out the worst of all
ideas: implementing yet-another pattern language and adding even more cognitive
load to an already arcane implementation of a Lisp language. Now Alan will have
to learn *two* pattern languages to debug Emacs instead of one, because pcase is
not going away. It will stay with us as long a Emacs lives, just like all other
Elisp constructs, unless you want to invalidate or rewrite all third-party code
out there, which is thousands of packages by now.
I am not a best writer and diplomat, but this link summarizes what I percieve
what pcase is trying to do, and cond* is just adding more of the same to it:
https://xkcd.com/927/
I understand the objections to pcase, but I don't understand the answer.
Best regards
/arthur
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-05 14:30 cond* vs pcase Arthur Miller
@ 2024-02-05 15:13 ` Eli Zaretskii
2024-02-05 16:06 ` Alfred M. Szmidt
1 sibling, 0 replies; 46+ messages in thread
From: Eli Zaretskii @ 2024-02-05 15:13 UTC (permalink / raw)
To: Arthur Miller; +Cc: emacs-devel
> From: Arthur Miller <arthur.miller@live.com>
> Date: Mon, 05 Feb 2024 15:30:57 +0100
>
> To start with, I think none on this mailing list has asked this question
> yet (or have I missed it?): why does it have to be a single form that does all
> of the pattern stuff?
Asked and answered: it doesn't have to be a single form that does all.
> Why this obsession that we have to have one form, be it pcase or cond*, that
> covers all cases of pattern usage in conditions?
There's no obsession.
> My second objection is, as many other stated here; if pcase is that hard,
> resource heavy, and underdocumented, have you considred working to fix problems
> and on the documentation of pcase, perhaps with Stefan?
We are doing that as well.
> I understand the objections to pcase, but I don't understand the answer.
Hopefully, now you understand it better.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-05 14:30 cond* vs pcase Arthur Miller
2024-02-05 15:13 ` Eli Zaretskii
@ 2024-02-05 16:06 ` Alfred M. Szmidt
2024-02-05 18:39 ` Philip Kaludercic
1 sibling, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-05 16:06 UTC (permalink / raw)
To: Arthur Miller; +Cc: emacs-devel
I use pcase often; but I use it just as a better cond. For example I find this
handy:
(defvar foo nil) <-- foo is some symbol
(pcase foo
('bar (do-some-bar-stuff))
('baz (do-some-baz-fluff)))
cl-case seems more appropriate here (wish cl-case was just case ...)
or this:
(setq foo "some-string")
(pcase foo
("foo" (do-foo-case))
("bar" (do-bar-case)))
Same here, with (intern foo) ...
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-05 16:06 ` Alfred M. Szmidt
@ 2024-02-05 18:39 ` Philip Kaludercic
2024-02-06 12:30 ` Arthur Miller
2024-02-06 16:17 ` Alfred M. Szmidt
0 siblings, 2 replies; 46+ messages in thread
From: Philip Kaludercic @ 2024-02-05 18:39 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: Arthur Miller, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> I use pcase often; but I use it just as a better cond. For example I find this
> handy:
>
> (defvar foo nil) <-- foo is some symbol
>
> (pcase foo
> ('bar (do-some-bar-stuff))
> ('baz (do-some-baz-fluff)))
>
> cl-case seems more appropriate here (wish cl-case was just case ...)
Why more appropriate? I always think of pcase as Elisp's case. In
addition, pcase avoids the danger of naively writing
(cl-case foo
('bar (do-some-bar-stuff))
('baz (do-some-baz-fluff)))
and then getting surprised when foo evaluates to `quote'.
> or this:
>
> (setq foo "some-string")
>
> (pcase foo
> ("foo" (do-foo-case))
> ("bar" (do-bar-case)))
>
> Same here, with (intern foo) ...
Being able to do equal instead of eql is also something that speaks in
favour of pcase...
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-05 18:39 ` Philip Kaludercic
@ 2024-02-06 12:30 ` Arthur Miller
2024-02-06 16:17 ` Alfred M. Szmidt
1 sibling, 0 replies; 46+ messages in thread
From: Arthur Miller @ 2024-02-06 12:30 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: Alfred M. Szmidt, emacs-devel
Philip Kaludercic <philipk@posteo.net> writes:
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
>> I use pcase often; but I use it just as a better cond. For example I find this
>> handy:
>>
>> (defvar foo nil) <-- foo is some symbol
>>
>> (pcase foo
>> ('bar (do-some-bar-stuff))
>> ('baz (do-some-baz-fluff)))
>>
>> cl-case seems more appropriate here (wish cl-case was just case ...)
>
> Why more appropriate? I always think of pcase as Elisp's case. In
> addition, pcase avoids the danger of naively writing
>
> (cl-case foo
> ('bar (do-some-bar-stuff))
> ('baz (do-some-baz-fluff)))
>
> and then getting surprised when foo evaluates to `quote'.
>
>> or this:
>>
>> (setq foo "some-string")
>>
>> (pcase foo
>> ("foo" (do-foo-case))
>> ("bar" (do-bar-case)))
>>
>> Same here, with (intern foo) ...
>
> Being able to do equal instead of eql is also something that speaks in
> favour of pcase...
Thanks Philip; that was an useful detail you pointed out. And thanks Alfred for
the suggestion too. I actually wanted to ask the same question as Philip, but I
didn't had time last night.
But what I am most thinking of, is this kind of quesionts and detail for people
to learn, and now we can add yet another case-like construct and perhaps slightly
different behaviour in similar cases, and there will be even more mine fields
for people to watch out and debug.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-05 18:39 ` Philip Kaludercic
2024-02-06 12:30 ` Arthur Miller
@ 2024-02-06 16:17 ` Alfred M. Szmidt
2024-02-06 16:35 ` [External] : " Drew Adams
2024-02-06 16:50 ` Philip Kaludercic
1 sibling, 2 replies; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-06 16:17 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: arthur.miller, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> I use pcase often; but I use it just as a better cond. For example I find this
> handy:
>
> (defvar foo nil) <-- foo is some symbol
>
> (pcase foo
> ('bar (do-some-bar-stuff))
> ('baz (do-some-baz-fluff)))
>
> cl-case seems more appropriate here (wish cl-case was just case ...)
Why more appropriate?
Because your not doing pattern matching, you're comparing against a
set of strings/symbols/numbers/....
I always think of pcase as Elisp's case. In
addition, pcase avoids the danger of naively writing
(cl-case foo
('bar (do-some-bar-stuff))
('baz (do-some-baz-fluff)))
and then getting surprised when foo evaluates to `quote'.
Suprises will happy, you will get suprises with pcase and cond* too --
I find it suprising that to match over symbols requires pattern
matching. One might also question why you (well, no you specifically)
are comparing against (quote bar) etc? That is a suprise in it self...
> or this:
>
> (setq foo "some-string")
>
> (pcase foo
> ("foo" (do-foo-case))
> ("bar" (do-bar-case)))
>
> Same here, with (intern foo) ...
Being able to do equal instead of eql is also something that speaks in
favour of pcase...
It speaks more in favor of having CASE where you can change the
comparison operator or a CASE-STRING or similar, not something much
more generic pcase (or even cond*!) -- i.e. why use pcase/cond* when
you're not using any of the features that are the main point of those
two macros.
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 16:17 ` Alfred M. Szmidt
@ 2024-02-06 16:35 ` Drew Adams
2024-02-06 16:50 ` Philip Kaludercic
1 sibling, 0 replies; 46+ messages in thread
From: Drew Adams @ 2024-02-06 16:35 UTC (permalink / raw)
To: Alfred M. Szmidt, Philip Kaludercic
Cc: arthur.miller@live.com, emacs-devel@gnu.org
>> Being able to do equal instead of eql is also
>> something that speaks in favour of pcase...
>
> It speaks more in favor of having CASE where
> you can change the comparison operator...,
> not something much more generic pcase (or
> even cond*!) -- i.e. why use pcase/cond* when
> you're not using any of the features that are
> the main point of those two macros.
Bingo. Just because `cl-case' is limited to
symbols and `eql', and just because Emacs has
relegated it to `cl-' instead of having its
own `case' for such things, is not a reason
to use `pcase' for such simple cases (trivial
"patterns").
`pcase' mixes powerful pattern-matching with
complex destructuring (binding). It's truly
overkill for trivial case-testing.
___
When you think that all you have in your tool
box is The Quantum Electronic Super Jackhammer,
you dress everything up as a fancy nail that
it can recognize and handle. Lipstick really
not needed. Not a code-obfuscation contest.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 16:17 ` Alfred M. Szmidt
2024-02-06 16:35 ` [External] : " Drew Adams
@ 2024-02-06 16:50 ` Philip Kaludercic
2024-02-06 17:27 ` Alfred M. Szmidt
` (2 more replies)
1 sibling, 3 replies; 46+ messages in thread
From: Philip Kaludercic @ 2024-02-06 16:50 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: arthur.miller, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
> > I use pcase often; but I use it just as a better cond. For example I find this
> > handy:
> >
> > (defvar foo nil) <-- foo is some symbol
> >
> > (pcase foo
> > ('bar (do-some-bar-stuff))
> > ('baz (do-some-baz-fluff)))
> >
> > cl-case seems more appropriate here (wish cl-case was just case ...)
>
> Why more appropriate?
>
> Because your not doing pattern matching, you're comparing against a
> set of strings/symbols/numbers/....
Simply because pattern matching is a more powerful generalisation,
capable of expressing case-distinction; in the end it compiles down to
almost the same code anyway.
> I always think of pcase as Elisp's case. In
> addition, pcase avoids the danger of naively writing
>
> (cl-case foo
> ('bar (do-some-bar-stuff))
> ('baz (do-some-baz-fluff)))
>
> and then getting surprised when foo evaluates to `quote'.
>
> Suprises will happy, you will get suprises with pcase and cond* too --
> I find it suprising that to match over symbols requires pattern
> matching. One might also question why you (well, no you specifically)
> are comparing against (quote bar) etc? That is a suprise in it self...
I don't understand your point here. If one expects the cases to be
evaluated, then quoting makes sense if you want to match a symbol. It
is not true, but common enough that the byte compiler emits a warning.
> > or this:
> >
> > (setq foo "some-string")
> >
> > (pcase foo
> > ("foo" (do-foo-case))
> > ("bar" (do-bar-case)))
> >
> > Same here, with (intern foo) ...
>
> Being able to do equal instead of eql is also something that speaks in
> favour of pcase...
>
> It speaks more in favor of having CASE where you can change the
> comparison operator or a CASE-STRING or similar, not something much
> more generic pcase (or even cond*!) -- i.e. why use pcase/cond* when
> you're not using any of the features that are the main point of those
> two macros.
I am sorry, but I don't follow your point here either. Is the general
claim, that one should only use whatever exactly and at most satisfies
the needs at hand?
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 16:50 ` Philip Kaludercic
@ 2024-02-06 17:27 ` Alfred M. Szmidt
2024-02-06 18:57 ` Philip Kaludercic
2024-02-06 17:29 ` [External] : " Drew Adams
2024-02-06 17:50 ` Thierry Volpiatto
2 siblings, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-06 17:27 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: arthur.miller, emacs-devel
> Because your not doing pattern matching, you're comparing against a
> set of strings/symbols/numbers/....
Simply because pattern matching is a more powerful generalisation,
capable of expressing case-distinction; in the end it compiles down to
almost the same code anyway.
Are you suggesting that COND/CASE/... and other "trivial" matching
constructs should be replaced with PCASE/COND*?
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 17:27 ` Alfred M. Szmidt
@ 2024-02-06 18:57 ` Philip Kaludercic
2024-02-06 19:04 ` Alfred M. Szmidt
` (2 more replies)
0 siblings, 3 replies; 46+ messages in thread
From: Philip Kaludercic @ 2024-02-06 18:57 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: arthur.miller, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> > Because your not doing pattern matching, you're comparing against a
> > set of strings/symbols/numbers/....
>
> Simply because pattern matching is a more powerful generalisation,
> capable of expressing case-distinction; in the end it compiles down to
> almost the same code anyway.
>
> Are you suggesting that COND/CASE/... and other "trivial" matching
> constructs should be replaced with PCASE/COND*?
No, just that using pcase in these cases isn't wrong.
Drew Adams <drew.adams@oracle.com> writes:
>> Simply because [1] pattern matching is a more
>> powerful generalisation, capable of expressing
>> case-distinction; [2] in the end it compiles
>> down to almost the same code anyway.
>
> Wow. Really _not_ a good reason (IMHO).
> Neither of those reasons [1,2] is good.
>
> With that reasoning you'll use `pcase'
> _always and everywhere_ - never `if',
> `cond', `let', `or', `and',...
Please don't be dishonest; My question was why cl-case was more
appropriate than pcase, where both are macros that boil down to simpler
primitives. I don't see an inherent advantage to using the more
specific abstraction over the more generic one. I like pcase, and
prefer using it in my code, but if you've got some code that is already
using a lot of cl-lib and no pcase, then there is no point in transiting
cl-case forms into pcase.
>
> Hey, `pcase' can do it all! And it
> compiles down to almost the same thing!
>
> "Demain on rase gratis !"
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 18:57 ` Philip Kaludercic
@ 2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-06 19:39 ` Philip Kaludercic
2024-02-06 19:12 ` Drew Adams
2024-02-07 5:32 ` Yuri Khan
2 siblings, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-06 19:04 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: arthur.miller, emacs-devel
> > Because your not doing pattern matching, you're comparing against a
> > set of strings/symbols/numbers/....
>
> Simply because pattern matching is a more powerful generalisation,
> capable of expressing case-distinction; in the end it compiles down to
> almost the same code anyway.
>
> Are you suggesting that COND/CASE/... and other "trivial" matching
> constructs should be replaced with PCASE/COND*?
No, just that using pcase in these cases isn't wrong.
Then we disagree on a fundamental level. This is just like like using
EQUAL when comparing stricly strings is not the right tool for the
job.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 19:04 ` Alfred M. Szmidt
@ 2024-02-06 19:39 ` Philip Kaludercic
2024-02-06 23:17 ` [External] : " Drew Adams
0 siblings, 1 reply; 46+ messages in thread
From: Philip Kaludercic @ 2024-02-06 19:39 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: arthur.miller, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> > > Because your not doing pattern matching, you're comparing against a
> > > set of strings/symbols/numbers/....
> >
> > Simply because pattern matching is a more powerful generalisation,
> > capable of expressing case-distinction; in the end it compiles down to
> > almost the same code anyway.
> >
> > Are you suggesting that COND/CASE/... and other "trivial" matching
> > constructs should be replaced with PCASE/COND*?
>
> No, just that using pcase in these cases isn't wrong.
>
> Then we disagree on a fundamental level. This is just like like using
> EQUAL when comparing stricly strings is not the right tool for the
> job.
"Alfred M. Szmidt" <ams@gnu.org> writes:
> Also interning strings just for the purpose of comparing them with eq or
> eql is questionable...
>
> So is pattern matching over characters, numbers, and other simple
> types...
In both cases here I think that there is a fundamental distinction
between functionality that is generic at compile-time and at run-time.
While `equal' vs `eq' is not pretty, the main issue for me here is that
you might accidentally compare and equate two string or lists that are
not the same object, which you sometimes don't want to do. Otherwise it
is not really slower than using `eq', if that is what concerns you:
--8<---------------cut here---------------start------------->8---
(benchmark-run 10000000
(eq 'foo 'bar))
;; (2.589085844 0 0.0)
(benchmark-run 10000000
(equal 'foo 'bar))
;; (2.611292045 0 0.0)
--8<---------------cut here---------------end--------------->8---
The pattern matching code is all generated at compile-time, and even
uses the `eq' to compare symbols, instead of the less specific `eql'
(!).
Yes, this might be a fundamental disagreement, but I still don't think
that using more abstract means to solve a problem is inherently wrong.
It might be a personal preference, but nothing we could derive a general
rule from -- which is fine.
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 19:39 ` Philip Kaludercic
@ 2024-02-06 23:17 ` Drew Adams
0 siblings, 0 replies; 46+ messages in thread
From: Drew Adams @ 2024-02-06 23:17 UTC (permalink / raw)
To: Philip Kaludercic, Alfred M. Szmidt
Cc: arthur.miller@live.com, emacs-devel@gnu.org
> [`equal'] is not really slower than using `eq'...
With this I agree completely. `equal' just calls
`eq' first thing, whenever it can (and I imagine
compiling even takes that out of the equation
often).
That said, _in such cases_ telegraphing the fact
that the Lisp objects can and should be compared
with `eq' _helps human readers_.
With a slight stretch of language, this can fall
under the heading of helping readers by expressing
"intent".
> The pattern matching code is all generated at compile-time, and even
> uses the `eq' to compare symbols, instead of the less specific `eql'
> (!).
Yes. It's not about performance.
> Yes, this might be a fundamental disagreement, but I
> still don't think that using more abstract means to
> solve a problem is inherently wrong.
It's not "inherently wrong", if you're measuring
"wrong" by performance - or perhaps even by some
other criteria.
> It might be a personal preference, but nothing
> we could derive a general rule from -- which is fine.
It is indeed a style question. But it doesn't
follow that stylistic guidelines don't, or can't,
or shouldn't exist.
The existing, documented Elisp guidelines don't
cover this. Nor do they cover other conventions
such as using `when'/`unless' to telegraph that
the returned value isn't important as such.
They could, but they don't. Such conventions
for conditionals do exist, and they're even
mentioned in CLTL2, IIRC (though CLTL2 doesn't
impose any style guidelines).
So yes, it's a personal stylistic preference.
Nevertheless, it doesn't hurt to discuss the
reasons for such a style - or for other styles.
Have we seen (here, now) any _reasons_ in favor
of always using `pcase' when something else
might do the job more simply? Have we seen an
argument an argument in _favor_ of "using more
abstract"?
I can think of a couple, but they don't convince
me in light of the "communicate intent" argument:
1. One can maybe save some time or effort by
learning only one construct (`pcase'). One
size fits all has a certain economy to it.
2. With `pcase', later updates might sometimes
not require as much editing.
I've never been an adoptee of the second. I
prefer to have the code always express better
the intent, even if that means I need to edit
it more later, when things change slightly.
This can easily be the case with conventions
about when to use `if', `and', `when', etc.,
for example.
A lot is in the eye of the beholder - the
expected readers of the code. Higher-order
functions such as `reduce' are elegant, and
their use can be succinct, for example.
(Elisp isn't a great fit for them, however.)
But a reader needs to have been introduced
to the genre.
YMMV. Different strokes for different folks.
More and less abstraction can each have their
advantages, even for human readers (not to
mention performance).
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 18:57 ` Philip Kaludercic
2024-02-06 19:04 ` Alfred M. Szmidt
@ 2024-02-06 19:12 ` Drew Adams
2024-02-06 20:08 ` Adam Porter
2024-02-07 5:32 ` Yuri Khan
2 siblings, 1 reply; 46+ messages in thread
From: Drew Adams @ 2024-02-06 19:12 UTC (permalink / raw)
To: Philip Kaludercic, Alfred M. Szmidt
Cc: arthur.miller@live.com, emacs-devel@gnu.org
> > Are you suggesting that COND/CASE/... and other "trivial" matching
> > constructs should be replaced with PCASE/COND*?
>
> No, just that using pcase in these cases isn't wrong.
>
> Drew Adams <drew.adams@oracle.com> writes:
>
> >> Simply because [1] pattern matching is a more
> >> powerful generalisation, capable of expressing
> >> case-distinction; [2] in the end it compiles
> >> down to almost the same code anyway.
> >
> > Wow. Really _not_ a good reason (IMHO).
> > Neither of those reasons [1,2] is good.
> >
> > With that reasoning you'll use `pcase'
> > _always and everywhere_ - never `if',
> > `cond', `let', `or', `and',...
>
> Please don't be dishonest;
Huh? Why would you think/claim I'm being
dishonest? Care to elaborate?
> My question was why cl-case was more
> appropriate than pcase, where both are macros that boil down to simpler
> primitives. I don't see an inherent advantage to using the more
> specific abstraction over the more generic one. I like pcase, and
> prefer using it in my code, but if you've got some code that is already
> using a lot of cl-lib and no pcase, then there is no point in
> transiting cl-case forms into pcase.
The inherent advantage is what I & others
have pointed out: clearer _intention
expression_ for human readers.
It says, in effect, "This just tests the
value for simple equality (using this or
that equality predicate)." It speaks
quietly, humbly, clearly.
`pcase' advertises instead: "Here come the
Big Guns, which can wrestle _anything_ to
the ground! Stand in awe and wonder."
No one is saying someone can't use `pcase'
for whatever they like. It's about style.
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 19:12 ` Drew Adams
@ 2024-02-06 20:08 ` Adam Porter
2024-02-06 23:32 ` Drew Adams
0 siblings, 1 reply; 46+ messages in thread
From: Adam Porter @ 2024-02-06 20:08 UTC (permalink / raw)
To: drew.adams; +Cc: ams, arthur.miller, emacs-devel, philipk
> It says, in effect, "This just tests the
> value for simple equality (using this or
> that equality predicate)." It speaks
> quietly, humbly, clearly. >
> `pcase' advertises instead: "Here come the
> Big Guns, which can wrestle _anything_ to
> the ground! Stand in awe and wonder."
CL-CASE and PCASE neither say nor advertise anything. They have no
personal qualities. They are macros, not people.
(pcase foo
('bar (do-some-bar-stuff))
('baz (do-some-baz-fluff)))
is not more awful or wonderful than:
(cl-case foo
(bar (do-some-bar-stuff))
(baz (do-some-baz-fluff)))
And neither of them is worse than what they expand to:
(cond ((eql foo 'bar)
(do-some-bar-stuff))
((eql foo 'baz)
(do-some-baz-fluff)))
Nor is this:
(pcase foo
(1 'ONE)
(2 'TWO)
((cl-type function) (funcall foo))
(_ 'SOMETHING-ELSE))
any worse than what it expands to:
(cond ((eql foo 1)
'ONE)
((eql foo 2)
'TWO)
((cl-typep foo 'function)
(funcall foo))
(t
'SOMETHING-ELSE))
That example is not even a case of pattern-matching, as no patterns are
involved.
But if one needed to add a pattern, as in the common case of a
customization option having various possible value types, one may easily
do so, as in:
(pcase foo
(1 'ONE)
(2 'TWO)
((cl-type function) (funcall foo))
(`(,fn . ,arg) (funcall fn arg))
(_ 'SOMETHING-ELSE))
I cannot fathom how this optionally available "power" is a problem which
should consign PCASE to only exceptional cases, any more than Lisp's
power should consign it to only a few libraries, leaving the rest to be
implemented in lower-level languages; or any more than Emacs's power
should consign it to only a few use cases, leaving the the rest to be
implemented in utilities to be piped together in a shell.
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 20:08 ` Adam Porter
@ 2024-02-06 23:32 ` Drew Adams
2024-02-07 13:14 ` Arthur Miller
0 siblings, 1 reply; 46+ messages in thread
From: Drew Adams @ 2024-02-06 23:32 UTC (permalink / raw)
To: Adam Porter
Cc: ams@gnu.org, arthur.miller@live.com, emacs-devel@gnu.org,
philipk@posteo.net
> (pcase foo
> ('bar (do-some-bar-stuff))
> ('baz (do-some-baz-fluff)))
>
> is not more awful or wonderful than:
>
> (cl-case foo
> (bar (do-some-bar-stuff))
> (baz (do-some-baz-fluff)))
Exactly. The difference is tiny when the
two are, uh, doing the same thing.
When `pcase' is used only to do what
`cl-case' is designed for, it doesn't
proclaim immediately to readers that
that's all it's doing.
___
However, our doc actually claims that a
`pcase' version of a similar example is
_superior_ to `cl-case' (not just-as-good).
https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68029
"This shows that you do need to use a `code'
variable (you named it `val' though), and
that the pcase version is indeed better."
(The `pcase' example actually uses _more_
variables than the `cl-case' example, in
spite of the doc claiming that it's better
because it uses fewer.)
If our doc and a maintainer can mistakenly
think `cl-case' is required to bind more
vars in such an example, then imagine how
mixed up a reader might be.
The point about using `cl-case' (or `cond'
or whatever else) in particular cases (vs
rather, using `pcase' in other cases) is
that doing so conveys the info that we're
talking about a simple or a not-so-simple
case.
If you use `pcase' for something for which
`cl-case' easily suffices, that can be less
clear than reserving `pcase' for heavier
lifting (when it's really needed).
Using them both, each for what it can offer,
can elucidate just what work is involved.
> And neither of them is worse than what they expand to:
> (cond ((eql foo 'bar)
> (do-some-bar-stuff))
> ((eql foo 'baz)
> (do-some-baz-fluff)))
>
> Nor is this:
> (pcase foo
> (1 'ONE)
> (2 'TWO)
> ((cl-type function) (funcall foo))
> (_ 'SOMETHING-ELSE))
>
> any worse than what it expands to:
> (cond ((eql foo 1)
> 'ONE)
> ((eql foo 2)
> 'TWO)
> ((cl-typep foo 'function)
> (funcall foo))
> (t
> 'SOMETHING-ELSE))
Of course. Did someone argue that `pcase'
doesn't compile or macroexpand to efficient
code?
It's a style/messaging question. Using
`pcase' for what `cl-case' can't do easily
and clearly can then say, "This here ain't
a straightforward `cl-case' thing."
You don't have to adopt such a convention.
But you can. Then when your readers see
`pcase' they'll pay attention, looking for
what _particularly called for_ using it.
> (pcase foo
> (1 'ONE)
> (2 'TWO)
> ((cl-type function) (funcall foo))
> (`(,fn . ,arg) (funcall fn arg))
> (_ 'SOMETHING-ELSE))
>
> I cannot fathom how this optionally available
> "power" is a problem which should consign PCASE
> to only exceptional cases
No one suggested that. Saying that it can
help to use `cl-case' when it perfectly fits
the bill is not the same as saying that one
should always use `cl-case'.
The argument is against always using `pcase';
it's not for always using `cl-case' (or `cond'
or...).
Use each for what it can do well/better. And
yes, it's only about coding style; it's not
about performance differences. (Maybe ask
yourself why you'd think the question is about
performance?)
> any more than Lisp's
> power should consign it to only a few libraries, leaving the rest to be
> implemented in lower-level languages; or any more than Emacs's power
> should consign it to only a few use cases, leaving the the rest to be
> implemented in utilities to be piped together in a shell.
That's precisely the point. One size might
stretch to fit all, but it's not necessarily
the best fit for everything.
Don't use a jackhammer to drive in a carpet
tack, if you have a tack hammer in your tool
belt. (But sure, you can always use the
jackhammer if you really want.)
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-06 23:32 ` Drew Adams
@ 2024-02-07 13:14 ` Arthur Miller
2024-02-07 13:43 ` Po Lu
2024-02-07 17:14 ` Drew Adams
0 siblings, 2 replies; 46+ messages in thread
From: Arthur Miller @ 2024-02-07 13:14 UTC (permalink / raw)
To: Drew Adams
Cc: Adam Porter, ams@gnu.org, emacs-devel@gnu.org, philipk@posteo.net
Drew Adams <drew.adams@oracle.com> writes:
>> (pcase foo
>> ('bar (do-some-bar-stuff))
>> ('baz (do-some-baz-fluff)))
>>
>> is not more awful or wonderful than:
>>
>> (cl-case foo
>> (bar (do-some-bar-stuff))
>> (baz (do-some-baz-fluff)))
>
> Exactly. The difference is tiny when the
> two are, uh, doing the same thing.
>
> When `pcase' is used only to do what
> `cl-case' is designed for, it doesn't
> proclaim immediately to readers that
> that's all it's doing.
> ___
>
> However, our doc actually claims that a
> `pcase' version of a similar example is
> _superior_ to `cl-case' (not just-as-good).
>
> https://debbugs.gnu.org/cgi/bugreport.cgi?bug=68029
>
> "This shows that you do need to use a `code'
> variable (you named it `val' though), and
> that the pcase version is indeed better."
>
> (The `pcase' example actually uses _more_
> variables than the `cl-case' example, in
> spite of the doc claiming that it's better
> because it uses fewer.)
>
> If our doc and a maintainer can mistakenly
> think `cl-case' is required to bind more
> vars in such an example, then imagine how
> mixed up a reader might be.
>
> The point about using `cl-case' (or `cond'
> or whatever else) in particular cases (vs
> rather, using `pcase' in other cases) is
> that doing so conveys the info that we're
> talking about a simple or a not-so-simple
> case.
>
> If you use `pcase' for something for which
> `cl-case' easily suffices, that can be less
> clear than reserving `pcase' for heavier
> lifting (when it's really needed).
>
> Using them both, each for what it can offer,
> can elucidate just what work is involved.
>
>> And neither of them is worse than what they expand to:
>> (cond ((eql foo 'bar)
>> (do-some-bar-stuff))
>> ((eql foo 'baz)
>> (do-some-baz-fluff)))
>>
>> Nor is this:
>> (pcase foo
>> (1 'ONE)
>> (2 'TWO)
>> ((cl-type function) (funcall foo))
>> (_ 'SOMETHING-ELSE))
>>
>> any worse than what it expands to:
>> (cond ((eql foo 1)
>> 'ONE)
>> ((eql foo 2)
>> 'TWO)
>> ((cl-typep foo 'function)
>> (funcall foo))
>> (t
>> 'SOMETHING-ELSE))
>
> Of course. Did someone argue that `pcase'
> doesn't compile or macroexpand to efficient
> code?
>
> It's a style/messaging question. Using
> `pcase' for what `cl-case' can't do easily
> and clearly can then say, "This here ain't
> a straightforward `cl-case' thing."
>
> You don't have to adopt such a convention.
> But you can. Then when your readers see
> `pcase' they'll pay attention, looking for
> what _particularly called for_ using it.
>
>> (pcase foo
>> (1 'ONE)
>> (2 'TWO)
>> ((cl-type function) (funcall foo))
>> (`(,fn . ,arg) (funcall fn arg))
>> (_ 'SOMETHING-ELSE))
>>
>> I cannot fathom how this optionally available
>> "power" is a problem which should consign PCASE
>> to only exceptional cases
>
> No one suggested that. Saying that it can
> help to use `cl-case' when it perfectly fits
> the bill is not the same as saying that one
> should always use `cl-case'.
>
> The argument is against always using `pcase';
> it's not for always using `cl-case' (or `cond'
> or...).
>
> Use each for what it can do well/better. And
> yes, it's only about coding style; it's not
> about performance differences. (Maybe ask
> yourself why you'd think the question is about
> performance?)
>
>> any more than Lisp's
>> power should consign it to only a few libraries, leaving the rest to be
>> implemented in lower-level languages; or any more than Emacs's power
>> should consign it to only a few use cases, leaving the the rest to be
>> implemented in utilities to be piped together in a shell.
>
> That's precisely the point. One size might
> stretch to fit all, but it's not necessarily
> the best fit for everything.
>
> Don't use a jackhammer to drive in a carpet
> tack, if you have a tack hammer in your tool
> belt. (But sure, you can always use the
> jackhammer if you really want.)
I think it is more important to be consistent and choose one form than many
different if possible. This is a discussion like should I choose setq vs setf.
I would agree with Norvig, check his guite to Lisp style from the PAIP book:
https://norvig.github.io/paip-lisp/#/chapter3?id=_31-a-guide-to-lisp-style
Prefering pcase over cl-case, mean you have one place to lookup the
documentation, one "special form" to learn, and so for your users too. A flora
and fauna of forms that do the very similar but slightly different is a *-case
for future bugs and problems.
I would be happy if we had only "let" with the powers of "let*" "set" with the
powers of "setf", "case" with the powers of "pcase" and so on.
Similar for del* and mem* funcitons. They are parametrized over comparison
operator, (memq, memql, member for example). It would be much better to have one
function that let us pass in comparison operator, say like this:
(member element list &optional test-function)
I would prefer it as a keyword argument so the API is similar to hashmap to be
more consistent. Similar for delete.
I understand those came historically, either as people discovered the
usefullness of them, or because the computers from the past where not powerful
enough so choosing one that cost least in terms of CPU or RAM resources was an
neccessity. But today, I think it is more of peep-hole optimizing. I think Paul
Graham is correct when he praises high-level "rapid-prototyping" features of
Lisp (I guess he wrote it before the term "agile programming" become popular):
https://sep.turbifycdn.com/ty/cdn/paulgraham/acl1.txt?t=1688221954&
"Signalling" something to someone by carefully crafting use of cl-case vs. pcase
sounds like a lot of cognitive load on all involved parties for very little
benefit. You are basically saying that we should use a high-level construct that
helps us structure our programs according to their implementation not for their
higher-level feature of singaling intention of our code.
As Adam point out; pcase let you specify the comparison function, is definitely
better than if we had some hypothetical caseq, caseql and case-equal.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 13:14 ` Arthur Miller
@ 2024-02-07 13:43 ` Po Lu
2024-02-07 17:09 ` Drew Adams
` (3 more replies)
2024-02-07 17:14 ` Drew Adams
1 sibling, 4 replies; 46+ messages in thread
From: Po Lu @ 2024-02-07 13:43 UTC (permalink / raw)
To: Arthur Miller
Cc: Drew Adams, Adam Porter, ams@gnu.org, emacs-devel@gnu.org,
philipk@posteo.net
Arthur Miller <arthur.miller@live.com> writes:
> Drew Adams <drew.adams@oracle.com> writes:
>
>>> (pcase foo
>>> ('bar (do-some-bar-stuff))
>>> ('baz (do-some-baz-fluff)))
>>>
>>> is not more awful or wonderful than:
>>>
>>> (cl-case foo
>>> (bar (do-some-bar-stuff))
>>> (baz (do-some-baz-fluff)))
Sorry to interject, but this really suggests that `cl-case' should
become, simply, `case', in subr.el this time around...
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-07 13:43 ` Po Lu
@ 2024-02-07 17:09 ` Drew Adams
2024-02-07 17:44 ` Tomas Hlavaty
` (2 subsequent siblings)
3 siblings, 0 replies; 46+ messages in thread
From: Drew Adams @ 2024-02-07 17:09 UTC (permalink / raw)
To: Po Lu, Arthur Miller
Cc: Adam Porter, ams@gnu.org, emacs-devel@gnu.org, philipk@posteo.net
> >>> (pcase foo
> >>> ('bar (do-some-bar-stuff))
> >>> ('baz (do-some-baz-fluff)))
> >>> is not more awful or wonderful than:
> >>> (cl-case foo
> >>> (bar (do-some-bar-stuff))
> >>> (baz (do-some-baz-fluff)))
>
> Sorry to interject, but this really suggests
> that `cl-case' should become, simply, `case',
> in subr.el this time around...
Dunno if it suggests that, but yes, I've
argued that for a long time. Emacs should
just adopt it as `case'. (It _used to be_
just `case', BTW, but it was in `cl.el'.)
And it wouldn't hurt for Emacs to allow an
optional TEST arg for the equality predicate.
That also serves as the membership predicate,
i.e., for clauses such as this:
((foo bar toto) (handle-foo-bar-and-toto))
(An optional KEY arg isn't needed, since
`case' is simple - it uses the same part of
the input value for all clauses - just apply
whatever KEY selector you need to the input
sexp. Another example of `case' simplicity.)
And adding optional TEST wouldn't bother
any existing uses of `cl-case'. `cl-case
could be aliased to the new `case' (or not).
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 13:43 ` Po Lu
2024-02-07 17:09 ` Drew Adams
@ 2024-02-07 17:44 ` Tomas Hlavaty
2024-02-09 3:52 ` Richard Stallman
2024-02-07 18:00 ` Arthur Miller
2024-02-12 21:39 ` Stefan Monnier via Emacs development discussions.
3 siblings, 1 reply; 46+ messages in thread
From: Tomas Hlavaty @ 2024-02-07 17:44 UTC (permalink / raw)
To: Po Lu, Arthur Miller
Cc: Drew Adams, Adam Porter, ams@gnu.org, emacs-devel@gnu.org,
philipk@posteo.net
On Wed 07 Feb 2024 at 21:43, Po Lu <luangruo@yahoo.com> wrote:
> Sorry to interject, but this really suggests that `cl-case' should
> become, simply, `case'
that would be great, also ecase would be good to have without cl-lib
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 13:43 ` Po Lu
2024-02-07 17:09 ` Drew Adams
2024-02-07 17:44 ` Tomas Hlavaty
@ 2024-02-07 18:00 ` Arthur Miller
2024-02-07 18:22 ` Alfred M. Szmidt
2024-02-08 5:01 ` Po Lu
2024-02-12 21:39 ` Stefan Monnier via Emacs development discussions.
3 siblings, 2 replies; 46+ messages in thread
From: Arthur Miller @ 2024-02-07 18:00 UTC (permalink / raw)
To: Po Lu
Cc: Drew Adams, Adam Porter, ams@gnu.org, emacs-devel@gnu.org,
philipk@posteo.net
Po Lu <luangruo@yahoo.com> writes:
> Arthur Miller <arthur.miller@live.com> writes:
>
>> Drew Adams <drew.adams@oracle.com> writes:
>>
>>>> (pcase foo
>>>> ('bar (do-some-bar-stuff))
>>>> ('baz (do-some-baz-fluff)))
>>>>
>>>> is not more awful or wonderful than:
>>>>
>>>> (cl-case foo
>>>> (bar (do-some-bar-stuff))
>>>> (baz (do-some-baz-fluff)))
>
> Sorry to interject, but this really suggests that `cl-case' should
> become, simply, `case', in subr.el this time around...
Pcase in that case, thanks.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 18:00 ` Arthur Miller
@ 2024-02-07 18:22 ` Alfred M. Szmidt
2024-02-08 1:55 ` Po Lu
2024-02-08 5:01 ` Po Lu
1 sibling, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-07 18:22 UTC (permalink / raw)
To: Arthur Miller; +Cc: luangruo, drew.adams, adam, emacs-devel, philipk
Po Lu <luangruo@yahoo.com> writes:
> Arthur Miller <arthur.miller@live.com> writes:
>
>> Drew Adams <drew.adams@oracle.com> writes:
>>
>>>> (pcase foo
>>>> ('bar (do-some-bar-stuff))
>>>> ('baz (do-some-baz-fluff)))
>>>>
>>>> is not more awful or wonderful than:
>>>>
>>>> (cl-case foo
>>>> (bar (do-some-bar-stuff))
>>>> (baz (do-some-baz-fluff)))
>
> Sorry to interject, but this really suggests that `cl-case' should
> become, simply, `case', in subr.el this time around...
That would be really nice (and maybe ecase, ccase as someone else
noted).
Pcase in that case, thanks.
pcase does not convey the same intent as either case or ecase. case
and ecase also have history, and are more familiar to people
programming Lisp (they are quite old, like many constructs -- so
suggestions like modifying cond outright should be disregarded point
blank).
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 18:22 ` Alfred M. Szmidt
@ 2024-02-08 1:55 ` Po Lu
2024-02-08 2:49 ` Philip Kaludercic
` (2 more replies)
0 siblings, 3 replies; 46+ messages in thread
From: Po Lu @ 2024-02-08 1:55 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: Arthur Miller, drew.adams, adam, emacs-devel, philipk
"Alfred M. Szmidt" <ams@gnu.org> writes:
> That would be really nice (and maybe ecase, ccase as someone else
> noted).
So provided that no serious objections emerge within the next couple of
days, I will install a change to this effect. Thanks.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-08 1:55 ` Po Lu
@ 2024-02-08 2:49 ` Philip Kaludercic
2024-02-08 3:36 ` Po Lu
2024-02-08 7:04 ` Eli Zaretskii
2024-02-08 17:01 ` Alfred M. Szmidt
2 siblings, 1 reply; 46+ messages in thread
From: Philip Kaludercic @ 2024-02-08 2:49 UTC (permalink / raw)
To: Po Lu; +Cc: Alfred M. Szmidt, Arthur Miller, drew.adams, adam, emacs-devel
Po Lu <luangruo@yahoo.com> writes:
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
>> That would be really nice (and maybe ecase, ccase as someone else
>> noted).
>
> So provided that no serious objections emerge within the next couple of
> days, I will install a change to this effect. Thanks.
Do you plan to move the definitions from cl-lib or provide new
definitions (someone mentioned being able to use equal instead of eq as
an extension)?
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-08 2:49 ` Philip Kaludercic
@ 2024-02-08 3:36 ` Po Lu
0 siblings, 0 replies; 46+ messages in thread
From: Po Lu @ 2024-02-08 3:36 UTC (permalink / raw)
To: Philip Kaludercic
Cc: Alfred M. Szmidt, Arthur Miller, drew.adams, adam, emacs-devel
Philip Kaludercic <philipk@posteo.net> writes:
> Do you plan to move the definitions from cl-lib or provide new
> definitions (someone mentioned being able to use equal instead of eq as
> an extension)?
Truth be told, I intended to use the definition of `case' from my own
init files, which is a copy from the old cl.el that has been lightly
modernized and requires neither cl nor cl-lib.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-08 1:55 ` Po Lu
2024-02-08 2:49 ` Philip Kaludercic
@ 2024-02-08 7:04 ` Eli Zaretskii
2024-02-08 17:01 ` Alfred M. Szmidt
2024-02-08 17:01 ` Alfred M. Szmidt
2 siblings, 1 reply; 46+ messages in thread
From: Eli Zaretskii @ 2024-02-08 7:04 UTC (permalink / raw)
To: Po Lu; +Cc: ams, arthur.miller, drew.adams, adam, emacs-devel, philipk
> From: Po Lu <luangruo@yahoo.com>
> Cc: Arthur Miller <arthur.miller@live.com>, drew.adams@oracle.com,
> adam@alphapapa.net, emacs-devel@gnu.org, philipk@posteo.net
> Date: Thu, 08 Feb 2024 09:55:27 +0800
>
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
> > That would be really nice (and maybe ecase, ccase as someone else
> > noted).
>
> So provided that no serious objections emerge within the next couple of
> days, I will install a change to this effect. Thanks.
Please don't. We don't have any real reason for doing this at this
time. The fact that the idea was popped up in a not-entirely-related
discussion is not a good reason for adding stuff to Emacs. The number
of callers of cl-case in our tree is not high enough to justify this.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-08 7:04 ` Eli Zaretskii
@ 2024-02-08 17:01 ` Alfred M. Szmidt
0 siblings, 0 replies; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-08 17:01 UTC (permalink / raw)
To: Eli Zaretskii
Cc: luangruo, arthur.miller, drew.adams, adam, emacs-devel, philipk
> From: Po Lu <luangruo@yahoo.com>
> Cc: Arthur Miller <arthur.miller@live.com>, drew.adams@oracle.com,
> adam@alphapapa.net, emacs-devel@gnu.org, philipk@posteo.net
> Date: Thu, 08 Feb 2024 09:55:27 +0800
>
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
> > That would be really nice (and maybe ecase, ccase as someone else
> > noted).
>
> So provided that no serious objections emerge within the next couple of
> days, I will install a change to this effect. Thanks.
Please don't. We don't have any real reason for doing this at this
time. The fact that the idea was popped up in a not-entirely-related
discussion is not a good reason for adding stuff to Emacs. The number
of callers of cl-case in our tree is not high enough to justify this.
The only reason for that is because cl-FOO has been activley
discouraged to be used, and active efforts to reduce cl-FOO usage was
done when the 'cl package became deprecated.
There are quite a bit of places where cl-case/case could have been
used, and pcase is used instead for no additional benefit.
Just because nothing uses it, doesn't mean that is a good argument to
not add it either.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-08 1:55 ` Po Lu
2024-02-08 2:49 ` Philip Kaludercic
2024-02-08 7:04 ` Eli Zaretskii
@ 2024-02-08 17:01 ` Alfred M. Szmidt
2024-02-09 1:30 ` Po Lu
2 siblings, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-08 17:01 UTC (permalink / raw)
To: Po Lu; +Cc: arthur.miller, drew.adams, adam, emacs-devel, philipk
> That would be really nice (and maybe ecase, ccase as someone else
> noted).
So provided that no serious objections emerge within the next couple of
days, I will install a change to this effect. Thanks.
If such things are added, then the Emacs Lisp reference manual should
be updated I think.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 18:00 ` Arthur Miller
2024-02-07 18:22 ` Alfred M. Szmidt
@ 2024-02-08 5:01 ` Po Lu
[not found] ` <DU2PR02MB10109B7AC39F995BFE266EF5396442@DU2PR02MB10109.eurprd02.prod.outlook.com>
1 sibling, 1 reply; 46+ messages in thread
From: Po Lu @ 2024-02-08 5:01 UTC (permalink / raw)
To: Arthur Miller
Cc: Drew Adams, Adam Porter, ams@gnu.org, emacs-devel@gnu.org,
philipk@posteo.net
Arthur Miller <arthur.miller@live.com> writes:
> Pcase in that case, thanks.
pcase is already preloaded, so what more could you ask for? As a matter
of fact, the present state of affairs, where pcase is preloaded but case
is not, is quite illogical--case is by a comfortable margin less
invasive and more generally applicable than is pcase.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-07 13:43 ` Po Lu
` (2 preceding siblings ...)
2024-02-07 18:00 ` Arthur Miller
@ 2024-02-12 21:39 ` Stefan Monnier via Emacs development discussions.
3 siblings, 0 replies; 46+ messages in thread
From: Stefan Monnier via Emacs development discussions. @ 2024-02-12 21:39 UTC (permalink / raw)
To: emacs-devel
>>>> (pcase foo
>>>> ('bar (do-some-bar-stuff))
>>>> ('baz (do-some-baz-fluff)))
>>>>
>>>> is not more awful or wonderful than:
>>>>
>>>> (cl-case foo
>>>> (bar (do-some-bar-stuff))
>>>> (baz (do-some-baz-fluff)))
>
> Sorry to interject, but this really suggests that `cl-case' should
> become, simply, `case', in subr.el this time around...
No, on the contrary. It just suggests that for this specific kind of
situations, either works about as well, so this is a use-case that would
not justify adding `pcase` if we already have `cl-case` (or `case`) and
it similarly would not justify adding `cl-case` (or `case`) if we
already have `pcase`.
Stefan "who would have preferred to extend `(cl-)case` rather
than introduce a new name, if it weren't for the fact
that the `(cl-)case` syntax does not lend itself to such
extensions"
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-07 13:14 ` Arthur Miller
2024-02-07 13:43 ` Po Lu
@ 2024-02-07 17:14 ` Drew Adams
1 sibling, 0 replies; 46+ messages in thread
From: Drew Adams @ 2024-02-07 17:14 UTC (permalink / raw)
To: Arthur Miller
Cc: Adam Porter, ams@gnu.org, emacs-devel@gnu.org, philipk@posteo.net
> > Don't use a jackhammer to drive in a carpet
> > tack, if you have a tack hammer in your tool
> > belt. (But sure, you can always use the
> > jackhammer if you really want.)
>
> I think it is more important to be consistent and
> choose one form than many different if possible.
The jackhammer is always "possible". That doesn't
mean that always using it is the best way to help
human readers of the source code.
> This is a discussion like should I choose setq
> vs setf.
In the abstract, it is. But the question isn't
abstract. This is about coding style. There's
no documented Elisp coding guideline about this,
so it comes down to personal preference/style.
> Prefering pcase over cl-case, mean you have one
> place to lookup the documentation, one "special
> form" to learn, and so for your users too.
When the "One Way" results in overly complicated
source code it can become an obstacle.
Let a hundred flowers bloom. You code your way
and I'll code mine. ;-)
I'm the main, maybe the only, reader of my code.
I use `if', `and', `when', etc., following the
convention I related. I do that _so that I_ can
more easily read and understand my own code
(sometimes years later). I do that for the same
reason that I sometimes add a comment with the
reasons behind some bit of code.
It's about human communication.
> It would be much better to have one function
> that let us pass in comparison operator, say
> like this:
> (member element list &optional test-function)
I agree. It would be good to have that (as in
Common Lisp), and I've said so multiple times.
That doesn't mean we should remove `memq'.
And even if `memq' didn't exist, that wouldn't
be a great argument against adding a `memq'.
> I think it is more of peep-hole optimizing.
Not at all. It's _not about performance_.
Dunno why people don't get that. It's about
human communication: code writer/reader.
Just like comments and API doc.
> "Signalling" something to someone by carefully
> crafting use of cl-case vs. pcase sounds like a
> lot of cognitive load on all involved parties
No - the opposite. And no one's required
to be sensitive to such nuances.
*IF* you know about the convention regarding
when to use `if', `and', `when', `cond',...
*THEN* you can immediately tell (even feel)
what's going on. This is as natural to
code writers and readers as writing/reading
(car foo) or (let...).
*IF* you're unaware of, or not used to, that
convention, *THEN* you just miss out on that
immediate "intuition"/understanding of what's
going on. You're not bothered at all.
But yes, you at least need to know what each
of `if', etc. does. That's really not hard.
It's not hard to learn what `case' does.
> You are basically saying that we should use a
> high-level construct that helps us structure
> our programs according to their implementation
> not for their higher-level feature of singaling
> intention of our code.
I'm absolutely NOT saying that. I'm saying that
communicating the intention of the code to human
readers is important.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 18:57 ` Philip Kaludercic
2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-06 19:12 ` Drew Adams
@ 2024-02-07 5:32 ` Yuri Khan
2024-02-07 12:43 ` Arthur Miller
2 siblings, 1 reply; 46+ messages in thread
From: Yuri Khan @ 2024-02-07 5:32 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: Alfred M. Szmidt, arthur.miller, emacs-devel
On Wed, 7 Feb 2024 at 01:58, Philip Kaludercic <philipk@posteo.net> wrote:
> Please don't be dishonest; My question was why cl-case was more
> appropriate than pcase, where both are macros that boil down to simpler
> primitives.
The design principle that Alfred alludes to is known as the [Rule of
Least Power][0]. That advocates using the least powerful construct
that still does the job. Like specialized mapcar instead of a
general-purpose while loop, or an http client instead of coding
directly against tcp sockets.
[0]: https://en.wikipedia.org/wiki/Rule_of_least_power
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-07 5:32 ` Yuri Khan
@ 2024-02-07 12:43 ` Arthur Miller
2024-02-07 17:41 ` Alfred M. Szmidt
0 siblings, 1 reply; 46+ messages in thread
From: Arthur Miller @ 2024-02-07 12:43 UTC (permalink / raw)
To: Yuri Khan; +Cc: Philip Kaludercic, Alfred M. Szmidt, emacs-devel
Yuri Khan <yuri.v.khan@gmail.com> writes:
> On Wed, 7 Feb 2024 at 01:58, Philip Kaludercic <philipk@posteo.net> wrote:
>
>> Please don't be dishonest; My question was why cl-case was more
>> appropriate than pcase, where both are macros that boil down to simpler
>> primitives.
>
> The design principle that Alfred alludes to is known as the [Rule of
> Least Power][0]. That advocates using the least powerful construct
> that still does the job. Like specialized mapcar instead of a
> general-purpose while loop, or an http client instead of coding
> directly against tcp sockets.
>
> [0]: https://en.wikipedia.org/wiki/Rule_of_least_power
I think it is a bad application of this principle in this context. Sitting an
deciding if there is a less-powerful condition form, or mapping functon for the
job sounds to me like a peep-hole optimization of Lisp, and as Monnier said
once, without benefit of the additional speed.
Before someone pulls out "eval"; that would be a completely different case, pun
intended.
I am not sure if Alfred meant that in his first message, perhaps he did, but
Drew seems to be more in line with that thinking. At least I understand him so.
If we going to have guiding principles that help us construct our programs, in
my opinion PAIP book by P. Norvig has few good advices:
* Be specific.
* Use abstractions.
* Be concise.
* Use the provided tools.
* Don't be obscure.
* Be consistent.
He sas:
"Sometimes, however, the maxims are in conflict, and experience will tell
you which one to prefer."
Than comes the example with push vs setf, with reasoning about both, which he
finnishes with following advice:
"Whichever choice you make on such issues, remember the sixth maxim: be
consistent."
Which I think is the most relevant for this discussion.
https://norvig.github.io/paip-lisp/#/chapter3
(It is Free to read and put online by the author himself.)
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-07 12:43 ` Arthur Miller
@ 2024-02-07 17:41 ` Alfred M. Szmidt
2024-02-07 18:36 ` Arthur Miller
0 siblings, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-07 17:41 UTC (permalink / raw)
To: Arthur Miller; +Cc: yuri.v.khan, philipk, emacs-devel
I am not sure if Alfred meant that in his first message, perhaps he did, but
Drew seems to be more in line with that thinking. At least I understand him so.
I'm not alluding to any specific design principle, the core issue at
hand is communicating with the person reading the code.
The reason why we have ASSOC, ASSQ, ... are because they make it
_clear_, _easy_ to understand code and to _use_. A generic version is
not as easy to understand, or use. Which is also a reason why
keywords are generally eskewed in Emacs Lisp.
So no, it would not be much better to have one function to rule them
all ... we have LAMBDA, and we sure do now want to write Y combinators
all over the place.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-07 17:41 ` Alfred M. Szmidt
@ 2024-02-07 18:36 ` Arthur Miller
2024-02-07 19:12 ` Alfred M. Szmidt
0 siblings, 1 reply; 46+ messages in thread
From: Arthur Miller @ 2024-02-07 18:36 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: yuri.v.khan, philipk, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> I am not sure if Alfred meant that in his first message, perhaps he did, but
> Drew seems to be more in line with that thinking. At least I understand him so.
>
> I'm not alluding to any specific design principle, the core issue at
> hand is communicating with the person reading the code.
Yes, that is how I understand you; but I'll answer same as to Drew; I don't
agree that this is the best way of expressing the intention.
Both pcase and cl-case in this particular simple context I have posted, express
the intention equally well. It is rather that you are aware of the details of
cl-case and pcase and understand that the pcase is more powerful and can express
more powerful constructs. However just that fact that it is more powerful, does
not mandate use of "simpler" construct. As Adam illustrated, in this particular
scenario, cond, cl-case and pcase expressed equally well the intention. The
runtime cost is about the same too; so I don't think the implementation deatails
should guide the decision. That seems to me like some sort of premature
optimization, peep-hole optimization of intentions. I am not sure how to express
myself here :).
> The reason why we have ASSOC, ASSQ, ... are because they make it
I am not sure if the reason is the clarity. I think we have, with all right,
gone away from abbrevs and accronys such as "assq" or "memql" in function and
variable names to more self-documenting code. Those functions are historical
artefacts in my eyes.
> _clear_, _easy_ to understand code and to _use_. A generic version is
> not as easy to understand, or use. Which is also a reason why
> keywords are generally eskewed in Emacs Lisp.
Is this not clear and understandable:
(member elt list #'eql)
(memeber elt list :test 'eql)
Can we be more explicit in communication the intention which test funciton to
use, if communicating exactly that intention is really important.
Approoos nameing and historical artefacts, I read once an interview with Ken
Thompson; I don't remember on which site, so I don't have the link, but they
were asking him a bit about Unix design and a bit about C language amongst other
things. On the question if he regret anything abotu Unix design, he said, if he
regret he used "creat" instead of "create" as the name for the syscall.
Best regards
/arthur
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-07 18:36 ` Arthur Miller
@ 2024-02-07 19:12 ` Alfred M. Szmidt
2024-02-07 21:20 ` Arthur Miller
0 siblings, 1 reply; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-07 19:12 UTC (permalink / raw)
To: Arthur Miller; +Cc: yuri.v.khan, philipk, emacs-devel
> I am not sure if Alfred meant that in his first message, perhaps he did, but
> Drew seems to be more in line with that thinking. At least I understand him so.
>
> I'm not alluding to any specific design principle, the core issue at
> hand is communicating with the person reading the code.
Yes, that is how I understand you; but I'll answer same as to Drew; I don't
agree that this is the best way of expressing the intention.
Both pcase and cl-case in this particular simple context I have posted, express
the intention equally well. [...]
We disagree to the point that there cannot be any agreement on the
topic, they do not express the same intent, just like a cond and
explicit (eql .. 'foo) do not express the same intent as using 'case';
they maybe do the same thing, but there is more about intent than
that.
As for tangents of optimizations, I'm not going to discuss them at
all.
It is rather that you are aware of the details of cl-case and pcase
and understand that the pcase is more powerful and can express more
powerful constructs. However just that fact that it is more
powerful, does not mandate use of "simpler" construct. As Adam
illustrated, in this particular scenario, cond, cl-case and pcase
expressed equally well the intention. The runtime cost is about the
same too; so I don't think the implementation deatails should guide
the decision. That seems to me like some sort of premature
optimization, peep-hole optimization of intentions. I am not sure
how to express myself here :).
> The reason why we have ASSOC, ASSQ, ... are because they make it
I am not sure if the reason is the clarity. I think we have, with all right,
gone away from abbrevs and accronys such as "assq" or "memql" in function and
variable names to more self-documenting code. Those functions are historical
artefacts in my eyes.
These functions are integral parts of Lisp, to call them "historical
artefacts" is to not understand or care to understand the language.
> _clear_, _easy_ to understand code and to _use_. A generic version is
> not as easy to understand, or use. Which is also a reason why
> keywords are generally eskewed in Emacs Lisp.
Is this not clear and understandable:
(member elt list #'eql)
(memeber elt list :test 'eql)
You missed a crucial part: to use. Writing code is also important.
But no, I do not find those clear at all, you have more symbols to
read, specially when comparing against common types like integers, or
symbols. You have the question of _why_ did the writer use that exact
form instead of already, well known, well documented, functions like
memql. So under no cirucmstance does the above mean clear or
understandable, rather it raises more questions.
Can we be more explicit in communication the intention which test funciton to
use, if communicating exactly that intention is really important.
Approoos nameing and historical artefacts, I read once an interview with Ken
Thompson; I don't remember on which site, so I don't have the link, but they
were asking him a bit about Unix design and a bit about C language amongst other
things. On the question if he regret anything abotu Unix design, he said, if he
regret he used "creat" instead of "create" as the name for the syscall.
I fail to see the point? Would you prefer mem-eql / member-eqal over
memql? They would do the same thing, which isn't the case comparing
pcase to case, cond to cond*, ...
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-07 19:12 ` Alfred M. Szmidt
@ 2024-02-07 21:20 ` Arthur Miller
0 siblings, 0 replies; 46+ messages in thread
From: Arthur Miller @ 2024-02-07 21:20 UTC (permalink / raw)
To: Alfred M. Szmidt; +Cc: yuri.v.khan, philipk, emacs-devel
"Alfred M. Szmidt" <ams@gnu.org> writes:
> > I am not sure if Alfred meant that in his first message, perhaps he did, but
> > Drew seems to be more in line with that thinking. At least I understand him so.
> >
> > I'm not alluding to any specific design principle, the core issue at
> > hand is communicating with the person reading the code.
>
> Yes, that is how I understand you; but I'll answer same as to Drew; I don't
> agree that this is the best way of expressing the intention.
>
> Both pcase and cl-case in this particular simple context I have posted, express
> the intention equally well. [...]
>
> We disagree to the point that there cannot be any agreement on the
> topic
Than lets agree to disagree and move on.
Anyway, thank you for your input!
Best regards
/arthur
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-06 16:50 ` Philip Kaludercic
2024-02-06 17:27 ` Alfred M. Szmidt
@ 2024-02-06 17:29 ` Drew Adams
2024-02-06 17:41 ` Alfred M. Szmidt
2024-02-06 17:50 ` Thierry Volpiatto
2 siblings, 1 reply; 46+ messages in thread
From: Drew Adams @ 2024-02-06 17:29 UTC (permalink / raw)
To: Philip Kaludercic, Alfred M. Szmidt
Cc: arthur.miller@live.com, emacs-devel@gnu.org
> Simply because [1] pattern matching is a more
> powerful generalisation, capable of expressing
> case-distinction; [2] in the end it compiles
> down to almost the same code anyway.
Wow. Really _not_ a good reason (IMHO).
Neither of those reasons [1,2] is good.
With that reasoning you'll use `pcase'
_always and everywhere_ - never `if',
`cond', `let', `or', `and',...
Hey, `pcase' can do it all! And it
compiles down to almost the same thing!
"Demain on rase gratis !"
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: [External] : Re: cond* vs pcase
2024-02-06 17:29 ` [External] : " Drew Adams
@ 2024-02-06 17:41 ` Alfred M. Szmidt
0 siblings, 0 replies; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-06 17:41 UTC (permalink / raw)
To: Drew Adams; +Cc: philipk, arthur.miller, emacs-devel
The reason why we use COND, CASE, .. ASSQ, ASSOC, ASSOC-STRING .. EQ, EQL,
=, STRING= is about _intent_, and communicating with the user.
E.g, CL-CASE is _infinitly_ easier to understand (basically COND with
implicit EQL) than a generalized "COND". That is not to say that a
"generalized" COND, or a COND that works over "patterns" (which is not
over types!) is not useful, they like many things have their place.
But they should be used when they make _sense_.
(pcase escape
(?% (insert "%"))
(?h (insert host))
(?n (insert (or port "")))
(?u (insert (or user "")))
(?p (insert (or pass "")))
(?f (insert (or file "/"))))))
The change was literally case -> pcase .. that does not make sense.
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 16:50 ` Philip Kaludercic
2024-02-06 17:27 ` Alfred M. Szmidt
2024-02-06 17:29 ` [External] : " Drew Adams
@ 2024-02-06 17:50 ` Thierry Volpiatto
2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-07 15:03 ` Barry Fishman
2 siblings, 2 replies; 46+ messages in thread
From: Thierry Volpiatto @ 2024-02-06 17:50 UTC (permalink / raw)
To: Philip Kaludercic; +Cc: Alfred M. Szmidt, arthur.miller, emacs-devel
Philip Kaludercic <philipk@posteo.net> writes:
> "Alfred M. Szmidt" <ams@gnu.org> writes:
>
>> "Alfred M. Szmidt" <ams@gnu.org> writes:
>>
>> > I use pcase often; but I use it just as a better cond. For example I find this
>> > handy:
>> >
>> > (defvar foo nil) <-- foo is some symbol
>> >
>> > (pcase foo
>> > ('bar (do-some-bar-stuff))
>> > ('baz (do-some-baz-fluff)))
>> >
>> > cl-case seems more appropriate here (wish cl-case was just case ...)
>>
>> Why more appropriate?
>>
>> Because your not doing pattern matching, you're comparing against a
>> set of strings/symbols/numbers/....
>
> Simply because pattern matching is a more powerful generalisation,
> capable of expressing case-distinction; in the end it compiles down to
> almost the same code anyway.
>
>> I always think of pcase as Elisp's case. In
>> addition, pcase avoids the danger of naively writing
>>
>> (cl-case foo
>> ('bar (do-some-bar-stuff))
>> ('baz (do-some-baz-fluff)))
>>
>> and then getting surprised when foo evaluates to `quote'.
>>
>> Suprises will happy, you will get suprises with pcase and cond* too --
>> I find it suprising that to match over symbols requires pattern
>> matching. One might also question why you (well, no you specifically)
>> are comparing against (quote bar) etc? That is a suprise in it self...
>
> I don't understand your point here. If one expects the cases to be
> evaluated, then quoting makes sense if you want to match a symbol. It
> is not true, but common enough that the byte compiler emits a warning.
>
>> > or this:
>> >
>> > (setq foo "some-string")
>> >
>> > (pcase foo
>> > ("foo" (do-foo-case))
>> > ("bar" (do-bar-case)))
>> >
>> > Same here, with (intern foo) ...
>>
>> Being able to do equal instead of eql is also something that speaks in
>> favour of pcase...
>>
>> It speaks more in favor of having CASE where you can change the
>> comparison operator or a CASE-STRING or similar, not something much
>> more generic pcase (or even cond*!) -- i.e. why use pcase/cond* when
>> you're not using any of the features that are the main point of those
>> two macros.
>
> I am sorry, but I don't follow your point here either. Is the general
> claim, that one should only use whatever exactly and at most satisfies
> the needs at hand?
Also interning strings just for the purpose of comparing them with eq or
eql is questionable...
--
Thierry
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 17:50 ` Thierry Volpiatto
@ 2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-07 15:03 ` Barry Fishman
1 sibling, 0 replies; 46+ messages in thread
From: Alfred M. Szmidt @ 2024-02-06 19:04 UTC (permalink / raw)
To: Thierry Volpiatto; +Cc: philipk, arthur.miller, emacs-devel
Also interning strings just for the purpose of comparing them with eq or
eql is questionable...
So is pattern matching over characters, numbers, and other simple
types...
^ permalink raw reply [flat|nested] 46+ messages in thread
* Re: cond* vs pcase
2024-02-06 17:50 ` Thierry Volpiatto
2024-02-06 19:04 ` Alfred M. Szmidt
@ 2024-02-07 15:03 ` Barry Fishman
2024-02-07 17:22 ` [External] : " Drew Adams
1 sibling, 1 reply; 46+ messages in thread
From: Barry Fishman @ 2024-02-07 15:03 UTC (permalink / raw)
To: emacs-devel
On 2024-02-06 17:50:01 GMT, Thierry Volpiatto wrote:
> Philip Kaludercic <philipk@posteo.net> writes:
>> "Alfred M. Szmidt" <ams@gnu.org> writes:
>>> "Alfred M. Szmidt" <ams@gnu.org> writes:
>>> Being able to do equal instead of eql is also something that speaks in
>>> favour of pcase...
>>>
>>> It speaks more in favor of having CASE where you can change the
>>> comparison operator or a CASE-STRING or similar, not something much
>>> more generic pcase (or even cond*!) -- i.e. why use pcase/cond* when
>>> you're not using any of the features that are the main point of those
>>> two macros.
>>
>> I am sorry, but I don't follow your point here either. Is the general
>> claim, that one should only use whatever exactly and at most satisfies
>> the needs at hand?
>
> Also interning strings just for the purpose of comparing them with eq or
> eql is questionable...
If I remember right, in Common Lisp long case statements could be optimized
by the compiler to do a hash lookup in a table generated at compile
time. The case form made it easy for the macro/compiler to figure this
out, and compilers were not as good as they are now.
Incidentally in Haskell, case is quite a different operation. There
the types are declared and know by the compiler, so it more a matter of
deconstructing a well defined type and possibly then checking the values to
meet some requirement. This is far simpler for Haskell programmers to
recognize than the more complex situation that pcase/cond* are trying
to solve.
What bothers me the most about it is that rather the breaking these
problems into simpler operations and providing a means of composing them
to handle more complex situation, the pcase/cond*/loop constructs mix
them all in to a single form.
This is defended by saying that it helps move some of the complexity
from the user to the macro processor. But like the current generation
of 'generative AI' solutions to problems, it seems to hide the
complexity in a way that subtle errors get hard to discover. New coders
end up spending their time copying code fragments rather than
understanding what is going on.
--
Barry Fishman
^ permalink raw reply [flat|nested] 46+ messages in thread
* RE: [External] : Re: cond* vs pcase
2024-02-07 15:03 ` Barry Fishman
@ 2024-02-07 17:22 ` Drew Adams
0 siblings, 0 replies; 46+ messages in thread
From: Drew Adams @ 2024-02-07 17:22 UTC (permalink / raw)
To: Barry Fishman, emacs-devel@gnu.org
> What bothers me the most about it is that rather [than]
> breaking these problems into simpler operations and
> providing a means of composing them to handle more
> complex situation, the pcase/cond*/loop constructs
> mix them all in to a single form.
>
> This is defended by saying that it helps move some of
> the complexity from the user to the macro processor.
> But like the current generation of 'generative AI'
> solutions to problems, it seems to hide the complexity
> in a way that subtle errors get hard to discover. New
> coders end up spending their time copying code fragments
> rather than understanding what is going on.
Indeed. (And maybe not just new coders.)
But there's room (a "case" to be made) for both:
1. Specific simple, combinable constructs:
`let', `case', `cond', `if', `when', `or',
`while', `dolist', `catch',...
2. More generic constructs that combine binding,
destructuring, and conditional/control:
`pcase', `cl-loop',...
What there's not a great "case" for is _always_
using #2, just because you can. You can, but
there can be a cost to your readers.
Occam's razor says _not to multiply things
unnecessarily_.
In this context, does that mean have just one,
generic, complex construct (don't multiply the
number of constructs)? Or does it mean use the
simplest, clearest construct in each particular
code context?
Does it add unnecessary noise to have a `case'
conditional, in addition to `pcase'? Or does
it add unnecessary noise to always use `pcase',
including in contexts where it's overkill?
Whether it's `pcase' or `cond*', combining
binding, destructuring, and conditional control
is a mouthful. It can be powerful, but it can
also be awful. And even when used correctly,
it can be overkill.
Should we purge Lisp of `let', `cond', `dolist',
and the rest, just because we can do everything
with `pcase' and `cl-loop'? Silly question, no?
Well that's really the question here. Let's add
`case' to Elisp (proper). And let's give it an
optional TEST argument.
^ permalink raw reply [flat|nested] 46+ messages in thread
end of thread, other threads:[~2024-02-12 21:39 UTC | newest]
Thread overview: 46+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-05 14:30 cond* vs pcase Arthur Miller
2024-02-05 15:13 ` Eli Zaretskii
2024-02-05 16:06 ` Alfred M. Szmidt
2024-02-05 18:39 ` Philip Kaludercic
2024-02-06 12:30 ` Arthur Miller
2024-02-06 16:17 ` Alfred M. Szmidt
2024-02-06 16:35 ` [External] : " Drew Adams
2024-02-06 16:50 ` Philip Kaludercic
2024-02-06 17:27 ` Alfred M. Szmidt
2024-02-06 18:57 ` Philip Kaludercic
2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-06 19:39 ` Philip Kaludercic
2024-02-06 23:17 ` [External] : " Drew Adams
2024-02-06 19:12 ` Drew Adams
2024-02-06 20:08 ` Adam Porter
2024-02-06 23:32 ` Drew Adams
2024-02-07 13:14 ` Arthur Miller
2024-02-07 13:43 ` Po Lu
2024-02-07 17:09 ` Drew Adams
2024-02-07 17:44 ` Tomas Hlavaty
2024-02-09 3:52 ` Richard Stallman
2024-02-07 18:00 ` Arthur Miller
2024-02-07 18:22 ` Alfred M. Szmidt
2024-02-08 1:55 ` Po Lu
2024-02-08 2:49 ` Philip Kaludercic
2024-02-08 3:36 ` Po Lu
2024-02-08 7:04 ` Eli Zaretskii
2024-02-08 17:01 ` Alfred M. Szmidt
2024-02-08 17:01 ` Alfred M. Szmidt
2024-02-09 1:30 ` Po Lu
2024-02-08 5:01 ` Po Lu
[not found] ` <DU2PR02MB10109B7AC39F995BFE266EF5396442@DU2PR02MB10109.eurprd02.prod.outlook.com>
2024-02-08 7:36 ` Sv: " Arthur Miller
2024-02-12 21:39 ` Stefan Monnier via Emacs development discussions.
2024-02-07 17:14 ` Drew Adams
2024-02-07 5:32 ` Yuri Khan
2024-02-07 12:43 ` Arthur Miller
2024-02-07 17:41 ` Alfred M. Szmidt
2024-02-07 18:36 ` Arthur Miller
2024-02-07 19:12 ` Alfred M. Szmidt
2024-02-07 21:20 ` Arthur Miller
2024-02-06 17:29 ` [External] : " Drew Adams
2024-02-06 17:41 ` Alfred M. Szmidt
2024-02-06 17:50 ` Thierry Volpiatto
2024-02-06 19:04 ` Alfred M. Szmidt
2024-02-07 15:03 ` Barry Fishman
2024-02-07 17:22 ` [External] : " Drew Adams
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.