unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* cond* Examples
@ 2025-01-06 14:55 Psionic K
  0 siblings, 0 replies; only message in thread
From: Psionic K @ 2025-01-06 14:55 UTC (permalink / raw)
  To: Emacs developers

I'm putting together some examples on Elisp forms and wanted to get
ahead regarding use cases where cond* is more ergonomic.

The closest example I can relate from other languages is a Rust match
statement, which both destructures and binds before taking one
matching arm.  Since cond-star's package docs say it's a replacement
for `pcase', that explanation is consistent at a surface level.

Regarding `bind*':
> it counts as true if the first binding's value is non-nil.

This feels inconsistent with `when-let*' and `if-let*' behavior, where
there's an intuitive reason that every bind must succeed for the first
or all body forms to evaluate.  Is this a first-pass tradeoff?

Regarding exit clauses
> and it exits the `cond*'
From this, I expected the next part:

> If a clause has only one element, or if its first element is
> t, or if it ends with the keyword :non-exit, then
> this clause never exits the `cond*' construct.  Instead,
> control falls through to the next clause (if any).
> The bindings made in CONDITION for the BODY of the non-exit clause
> re passed along to the rest of the clauses in this `cond*' construct.

Yeah, okay, so we're definitely evaluating multiple BODYs in some cases.

I read the tests, new manual section, and news.  I couldn't find the
mailing list entries since I didn't subscribe and while I'm positive
I've seen many cond* threads, no query that I provided Namazu was
effective.

In any case, the goal is to identify 1) the point where cond* becomes
necessary.  For example, in the case of let*, I can say that whenever
bindings become dependent, it is necessary to use let*.  2) where
cond* becomes advantageous.  For example, when using let* over its
equivalent sequentially nested let form, the advantage is readily
evident in the reduction of form repetition.  It's natural that
necessity and advantage tend to go together here.

From what I can gather and deduce, cond* is a variation of a cond
where I want to compose several destructurings into the same scope,
conditionally, so the equivalent in Elisp today will compose several
logic and pcase expressions, and this may lead to some repetitive
binding until the natural flow of the logic is discovered.  While
cond* seems capable of short-circuiting this repetition by propagating
binds, I am less clear on natural cases where I want to bind from an
inner rather than outer form.  Compared to let*, the existence of many
inner macro calls makes me wonder what I am compressing out.  Why not
a sequential match* for such a composition of dependent destructuring
binds and then no repetition of match* in the inner forms?

In fact, I fear the use of cond* for its expression of both logic and
destructuring within one macro will obfuscate the purpose of why it
was employed.  It does almost everything.  As for what is not
included, it can't be used for looping except as an inner form.  How
intensely jealous I am of Clojure, Rust, and Python, where
destructuring is quite natural in the other elementary forms,
including iteration, logic, and binding.

I do sense some idea trying to get out.  If the destructuring form is
not understood by let, let*, if-let* etc, then we are forced to choose
between destructuring and logic.  Other languages are blessed with
both and profit greatly from it.  Cond does seem to be reaching
towards such a composition.

One idea I like from cond* (at least described in the documentation
that I was unable to find in the implementation of) is this notion
that the form is limited to comprehending other symbols bearing the
"cond-star property" as clauses.

It all makes me intensely jealous of languages for which every
conditional binding or iterative binding form can also destructure.
What a magical world if let, while-let, and if-let could destructure
and if let itself could be composed with a conditional expression
without a distinct macro such as the one named if-let.

If only there was a tool to dispense with redundant parentheses around
inner calls to further macros.



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-01-06 14:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-06 14:55 cond* Examples Psionic K

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