Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through args of macro

I am trying to write a macro in Clojure that allows for evaluation of a series of simple "def" expressions. I am a n00b when it comes to macros. The idea is that

(my-defs y1 1
     y2 "taco")

should expand to

(do (def y1 1) (def y2 "taco"))

The following code accomplishes this for the special case of two defs

(defmacro my-defs 
  [& args]
  `(do
     (def ~(first args) ~(second args))
     (def ~(nth args 2) ~(nth args 3) )))

which is nice, but I am having trouble generalizing this. I tried out a few naive things involving looping through bindings of the elements of (partition 2 args) but I always got garbage (I know this isn't very specific but the diversity and extent of the garbage seemed a bit too much to report here). How do I loop over these are and evaluate my defs?

P.S. The macro my-defs is a toy. What i really want to accomplish in the end is a littel helper macro to instantiate a bunch of multimethod instances. Currently I have large chunks of code that look like

(defmethod f [A B] [x] "AB")
(defmethod f [A A] [x] "AA")
(defmethod f [C B] [x] "CB")

which is a little unsightly. It would be nice if I could do something like

(defmethods f
  [A B] [x] "AB"
  [A A] [x] "AA"
  [C B] [x] "CB")

instead.

like image 670
Gabriel Mitchell Avatar asked Sep 05 '11 22:09

Gabriel Mitchell


1 Answers

It looks to me like you're looking for the ~@ macro expansion/unquote.

(defmacro defmethods [n & defs] 
   `(do ~@(map (fn [[a1 a2 a3]] 
                   `(def ~n ~a1 ~a2 ~a3)) 
               (partition 3 defs))))
like image 97
Joost Diepenmaat Avatar answered Nov 03 '22 11:11

Joost Diepenmaat