I have an arbitrary number of lists which I would like to process using the for macro. I want to create a function that passes a vector as the binding since the number of lists
You can try to force the evaluation of the binding vector. Instead of trying to define a macro that will wrap the for
macro, wrap it in a function, e.g.
(defn for-fn [bindings expr]
(eval `(for ~bindings ~expr)))
Then you can actually build a binding vector with a few additional constraints since all s-expressions inside the binding vector need to be valid and contain a verb as the first element.
(let [bindings '[a (list 1 2) b (list 3 4) c (range 10 12)
:when (> (+ a b c) 15)]
expr '(str a "-" b "-" c)]
(for-fn bindings expr))
And with your example :
(def list1 '("pink" "green"))
(def list2 '("dog" "cat"))
(def testvector (vector 'A (cons 'list list1) 'B (cons 'list list2)))
(for-fn testvector '(str A "-" B))
=> ("pink-dog" "pink-cat" "green-dog" "green-cat")
Note : since for-fn
is function, you need to quote the expression (str A "-" B)
to prevent an early evaluation (before A & B are bound).