On Dec 3, 2:51 pm, Meikel Brandmeyer <[EMAIL PROTECTED]> wrote:
> Hi Stuart and Rich,
>
> Am 03.12.2008 um 19:00 schrieb Stuart Sierra:
>
> >> I'm pretty sure I don't like the sound of that at all. We had a nice
> >> discussion about fcase/condf, which I'd like to get in, here:
>
> >>http://groups.google.com/group/clojure/browse_frm/thread/
> >> dee910bef629...
>
> > And I haven't forgotten about that, just haven't had time to work on
> > it. Anyone else who wants to tackle it is welcome.
>
> How about the following:
>
> (defmacro condp
> "condp compares the given needle with the first clause using the
> given
> predicate. In case the predicate returns true the second clause is
> returned. Otherwise condp goes on with the rest of the clauses. In
> case there is an odd number of clauses the last one will be returned
> if no preceding clause matched. If no default clause is given an
> exception is thrown. The predicate is called with needle as first
> argument and the first clause as second argument."
> [pred needle & clauses]
> (let [c (count clauses)
> par (rem c 2)
> cls (take (if (zero? par) c (dec c)) clauses)
> cls (mapcat (fn [[x c]] `[(~xprd ~xndl ~x) ~c]) (partition 2
> cls))
> xndl (gensym "condp_needle__")
> xprd (gensym "condp_predicate__")
> lst (if (zero? par)
> `(throw (Exception. (str "No condp clause matched for: "
> (prn-str ~xndl))))
> (last clauses))]
> `(let [~xprd ~pred
> ~xndl ~needle]
> (cond
> [EMAIL PROTECTED]
> :else ~lst))))
>
> I mulled about the (x _) syntax, but to be honest: I think #() is
> perfectly sufficient. We would need to quote all the contents to
> prevent multiple evaluation, but then we have to recurse and check
> for _ vs. non-_...
>
> I expect the predicate to be a function of two arguments with the first
> being the needle and the second being the clause, we compare to.
> Predicates where order doesn't matter or the order agrees may be simply
> used. Others or more complicated expressions can be wrapped in a #().
> Here we still have a problem for #(pred (complicated-computation) %2
> %1)....
>
> In case the number of clauses is even, and no clause matched the
> predicate, we throw an exception. In case the number of clauses is
> odd, we return the last one as default. I think adding a simple nil
> is tolerable, making the "I ignore a failed run" explicit.
>
> What do you think?
>
needle is a strange name - what's the origin? expr is probably better.
I'm ok with odd clause is default, else throw if not match.
I think the expr should be passed second to the fn - in most cases
where it matters, that is a more useful default:
contains?, re-find, instance? etc.
I almost whipped this up yesterday, but I got sidetracked thinking
about how best to provide a feature like Scheme's cond's =>. Do you
know it? It feeds the value of the test to the fn on the rhs of the
clause. It can be useful.
Rich
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---