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

Attachment: smime.p7s
Description: S/MIME cryptographic signature

Reply via email to