[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Code for cond*
From: |
JD Smith |
Subject: |
Re: Code for cond* |
Date: |
Tue, 23 Jan 2024 23:49:06 -0500 |
In general I’ve always felt cond by itself was missing some functionality and
could really use the ability to make bindings — a cond-let if you will. Even
making and testing bindings local to each cond clause would be a real
advance[1]. Pattern matching adds another level of complexity I hadn’t
considered, but overall I'm supportive of efforts to improve cond.
I’ve used pcase lightly, but to be honest have always winced when I have
encountered it in code I really need to understand. As others have already
discussed, the similar looking but in fact semantically distinct domain
language has always thrown me (unlike cl-loop, whose language is not easily
mistaken for regular elisp syntax).
But oddly enough, this thread discussing its potential replacement has given me
the key insight — “imagine running list interpolation backwards”. With that
mental model, I find I can now read pcase forms much more easily and
confidently. A short introductory paragraph in the elisp pcase documentation
which explains this approach to its novel syntax would have gone a long way for
me.
> On Jan 23, 2024, at 1:10 PM, Stefan Monnier via Emacs development
> discussions. <emacs-devel@gnu.org> wrote:
>
>> ((match* `(expt ,foo ,bar) x))
>> ;; Bindings continue in effect.
>
> Same comment as before: I like having both "bindings for the clause"
> and "bindings for the rest", but having the two be syntactically
> identical will lead to confusion.
This is a significant concern. If I’m understanding the design correctly:
(let ((var outer-value))
(cond*
((bind* (var (some-complicated-function-that-returns-nil))))
((bind* (other-var (some-other-function))))
<... lots of other clauses>
(t var)))
would return a different final fall-back value than the nearly identical form:
(let ((var outer-value))
(cond*
((bind* (var (some-complicated-function-that-returns-nil))) t) ; <-- hidden
danger
((bind* (other-var (some-other-function))))
<... lots of other clauses>
(t var)))
with a single `t’ added, perhaps a page above, deep inside a sibling clause.
That kind of “spooky action at a distance” would in my view lead to hard to
track down errors and difficult to parse code.
Perhaps let* could be used for binding variables within clauses, and bind* for
bindings which remain in effect for the rest of the construct, ignoring any
final value given in the ((bind* )) clause. But even with that disambiguation,
I’m so used to “looking upwards to a parent let-form for the active bindings”
that establishing bindings in a sibling clause like this would take some
getting used to.
[1] I regularly convince myself that it’s such low hanging fruit, there must in
fact already BE a cond-let, and I go hunting for it. The obvious interface
seems like such a straightforward extension of if/when-let, that there would be
absolutely nothing new to learn:
(cond-let
(((var value)
(dvar (derived-from var))
((has-the-right-stuff-p dvar)))
(cons 'correct dvar))
(((foo value2)
(bar (1- foo))
((< bar 0)))
(cons 'incorrect bar))
(t nil))
- Re: Code for cond*, (continued)
- Re: Code for cond*, Emanuel Berg, 2024/01/24
- Re: Code for cond*, Alan Mackenzie, 2024/01/24
- Re: Code for cond*, Emanuel Berg, 2024/01/24
- Re: Code for cond*, Po Lu, 2024/01/25
- Re: Code for cond*, Emanuel Berg, 2024/01/25
- Re: Code for cond*, Po Lu, 2024/01/25
Re: Code for cond*, Richard Stallman, 2024/01/19
Re: Code for cond*, Stefan Monnier, 2024/01/23
- Re: Code for cond*,
JD Smith <=
- Re: Code for cond*, Stefan Kangas, 2024/01/24
- Re: Code for cond*, JD Smith, 2024/01/24
- Re: Code for cond*, Stefan Monnier, 2024/01/24
- Re: Code for cond*, Stefan Monnier, 2024/01/24
- Re: Code for cond*, JD Smith, 2024/01/24
- Re: Code for cond*, Stefan Monnier, 2024/01/24
- RE: [External] : Re: Code for cond*, Drew Adams, 2024/01/24
RE: [External] : Re: Code for cond*, Drew Adams, 2024/01/24
Re: Code for cond*, Madhu, 2024/01/25
Re: Code for cond*, Stefan Monnier, 2024/01/25