(my-cond
(:let var value)
(:let dvar (derived-from var))
((has-the-right-stuff-p dvar)
(cons 'correct dvar))
(:let foo value2)
(:let bar (1- foo))
((< bar 0)
(cons 'incorrect bar))
(t nil))
On Friday I started looking at something along the same lines. I sent
two messages about it. It has the same features as cond*, using a
syntax something like the above.
In a separate subthread (and offline) I've been discussing a simple `cond-let', envisioned as part of the if/when-let family (it has no pattern matching capabilities). It does, as you'd expect, offer local bindings for each clause.
On Jan 28, 2024, at 10:19 PM, Richard Stallman <rms@gnu.org> wrote:
Here is the new version. I made a test framework for it
and have used that to verify a number of test cases.
...
`(bind* BINDINGS...)' means to bind BINDINGS (as if they were in `let*')
for the body of the clause. As a condition, it counts as true
if the first binding's value is non-nil. All the bindings are made
unconditionally for whatever scope they cover.
I wonder why (bind*) evaluates only its first value to determine if the binding condition is true? We already have macros which evaluate the "truth of a set of bindings": the members of the if-let family. And they
"Evaluate each binding in turn, as in ‘let*’, stopping if a binding value is nil. If all are non-nil return the [final] value."
I would personally find this behavior for variables bound locally within clauses easier to remember and more useful. Users will already be familiar with it (from if-let), and it supports plain (VALUE) "bindings" for when you'd like to mix actual variable bindings and other tests in a given clause's CONDITION.
Attached is a simple cond-let design (again, just a simple extension of if/when-let, no pattern matching). You notice that rather than using any particular keyword sigil like :let or bind*, it simply checks if the CONDITION of a clause is a list-of-lists, in which case it is interpreted as a binding spec. The only small addition to if/when-let's binding handling is for plain (CONDITION-BINDING-SPEC) clauses; in that case, if all binding values are non-nil, the final value is returned from cond-let.