I've been working on a def-casemacro macro and I've run into some trouble. The macro defines smaller macros based on a supplied name and test function. Each one evaluates the first argument and then uses the test to compare the result to each supplied case, evaluating whatever returns true or raising an error otherwise. Your basic ecase like macros.
I've made macros like this in Common Lisp befor without any trouble but in clojure the ` reader macro seems to namespace qualify everything inside of it. This causes Clojure to freek out about all my variables and arguments. So far the only solution I've found is to stick ~' infront of each variable I use. But this is less then ideal cause you end up 2 or 3 backticks in with stuff like ~~' infront of every local variable. Honetsly I'm not sure what could be done about this, I just wanted to point it out in case it hasn't been already. Anyway I got it to work, so for those intrested, here it is: (defn pair-seq [seq] (if seq (lazy-cons [(first seq) (second seq)] (pair-seq (rrest seq))) nil)) (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)) [~'form & ~'key-result-pairs] (let [~'key-gen (gensym "key__") ~'kr-pairs (pair-seq ~'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 " '~casename " for key: %s") (str ~~'key-gen))))))))) ;; Examples (def-casemacro case =) (def-casemacro instance?-case instance?) (def-casemacro identical?-case identical?) (def-casemacro isa?-case isa?) ;;Umm... Meta-Examples? (comment (case (first '(:foo :bar :biz)) :bar 5 :foo 7 :biz 6) => 7 (instance?-case "foo bar" (if true String Double) 'yay! Integer 'boo...) => yay! (contains?-case #{:foo :bar :biz} :foo 5 :bar 2 :biz 3) => 5 (isa?-case (class "foo") FileInputStream :file-stream InputStream :istream String :string) => :string etc... ) -- -Nate --~--~---------~--~----~------------~-------~--~----~ 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 clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---