Reported by m...@kotka.de, Dec 17, 2008
fcase from clojure.contrib is planned to be included in clojure.core
as condp. Currently there are two suggestions, on how to implement
The attached patch proposes the following form:
(condp predicate expr
For each pair test-expr and result-expr the predicate will
be called in the form (predicate test-expr result-expr). If
the predicate returns true, the result-expr is executed.
Using the vector binding form as known from let and friends
one might also assign the result of the call to predicate to
a local which may be used in the result-expr.
(condp [local predicate] expr
If the number of test-expr result-expr pairs is odd, then
the last clause is evaluated, in case no previous clause was
chosen by the predicate. If the number of pairs is even,
an exception is thrown.
Furthermore the following changes to cond are proposed
to implement functionality similar to clojure.contrib.cond-let.
[local test-expr] result-expr
In case the test-expr in cond is a vector the first item is
used as the name of local which is bound to result of the
test-expr (second item in the vector) in result-expr.
This patch is backward-compatible.
Additionally another solution using templates was proposed
on the google group. More information on this proposal
may be found in the following thread:
2.9 KB Download
Comment 1 by richhickey, Dec 17, 2008
You meant: (predicate test-expr expr) right?
I think we should take any changes to cond off the table at present.
It would be nicer if condp could do binding on a per-clause basis, as you did for
cond, but doing it the same way would rule out vectors as test exprs (with predicates
like nth, I guess).
The alternative is Scheme's:
test-expr => result-fn
where result-fn is a fn of one arg, passed the result of the predicate.
This can end up being more compact. I guess in Clojure we'd use a keyword:
test-expr :> result-fn
Comment 2 by m...@kotka.de, Dec 18, 2008
Modified the implementation. The syntax is now as follows:
(condp predicate expr
test-expr :> result-expr
In the first case result-expr is evaluated and its result is returned
if (predicate test-expr expr) returns non-nil/non-false.
In the second case, result-expr is expected to evaluate to a function
of one argument, which is passed the result of the predicate call.
Again: only if the result of the predicate call is non-nil/non-false.
In case there is a single clause at the end which does not fit the above
patterns it is taken as default in case no test-expr yields a success.
If no such default is given an exception is thrown.
The patterns may be freely mixed.
Cond is not modified.
2.6 KB Download
Comment 3 by richhickey, Dec 21, 2008
In the end I found these patches too complex and wrote my own, thanks for the input!