Hi, first things first: what you want to do is available as condp in the core library of Clojure. That said, here some things I noticed in your macro.
You should not capture variables in your macros. That's bad style and might lead to clashes of names. Clojure provides the foo# notation to generate new symbols via gensym. This makes a call to gensym almost always unnecessary. Your pair-seq function may be written using the partition function from the seq-library: (pair-seq the-seq) <=> (partition 2 the-seq). One may specify a map between the argument vector and the docstring of functions and macros. This map becomes part of the metadata. Here this may be used to get some nice argument names in the doc output for the generated macro instead of the gensym names. Here we go: (defmacro def-casemacro [casename test]"Defines a macro named casename that uses test to compair the result of
form to each key/result pair" `(defmacro ~casename~(format "Evaluates form and finds the first key/result pair that %s is true for, evaluates it and returns the result. Error if none is found."
(print-str test)) {:arglists '([~'form ~'key-result-pairs])} [form# & key-result-pairs#] (let [key-gen# (gensym "key__") kr-pairs# (partition 2 key-result-pairs#)] `(let [~key-gen# ~form#] (cond ~@(mapcat (fn [[key# result#]]`((~'~test ~key-gen# ~key#) ~result#)) kr- pairs#)
true (throw (new Error (format ~(str "No %s for key: %s") ~~(name casename) (str ~key-gen#))))))))) This works for me at least for the case (def-casemacro case =). Hope this helps. Sincerely Meikel
smime.p7s
Description: S/MIME cryptographic signature