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? Sincerely Meikel
smime.p7s
Description: S/MIME cryptographic signature