On Thu, Apr 19, 2012 at 7:28 AM, Thomas <thomas.ka...@googlemail.com> wrote: > Hi, > > I'd like to write a macro which transforms > > (my-macro SomeClass. a b [x y] c [e f]) > > into > > (SomeClass. a b x y c e f) > > (the order of collections and single values in the arguments should be > arbitrary) > > The closest I came was > > (defmacro my-macro [func & args] > `(~func ~@(flatten args))) > > This works for simple cases like > > (my-macro SomeClass. 1 2 [3 4] 5) > > but clearly breaks when I do > > (def a [1 2]) > (def b [3 4]) > (my-macro SomeClass. a b) > > since > > (macroexpand-1 '(my-macro SomeClass. a b)) > => (SomeClass. a b) > > "flatten" seems the wrong way to do that. But I somehow need to > evaluate the forms in the args before the unqoute splice happens. > How would I do that? > > An alternative would be to generate forms like > > (apply #(SomeClass. %1 %2 %3 %4 %5) (concat [1] [2] [3 4] [5])) > > but I don't have an idea how to do that plus it has one additional (un- > necessary?) level of indirection > > Any hints would be greatly appreciated.
The proper approach is something close to the latter. Try: (defn flatten-1 "Flattens a coll by one level only." ([coll] (apply concat (map #(if (coll? %) (list %) %) coll)))) (defmacro wrap-in-fn [x] `(fn ([] (~x)) ([a1#] (~x a1#)) ([a1# a2#] (~x a1# a2#)) ([a1# a2# a3#] (~x a1# a2# a3#)) ([a1# a2# a3# a4#] (~x a1# a2# a3# a4#)) ([a1# a2# a3# a4# a5#] (~x a1# a2# a3# a4# a5#)) ([a1# a2# a3# a4# a5# a6#] (~x a1# a2# a3# a4# a5# a6#)) (comment ... and any higher arities you think you need ...))) (defmacro my-macro [x & args] `(apply (wrap-in-fn ~x) (flatten-1 (list ~@args)))) -- 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 Note that posts from new members are moderated - please be patient with your first post. 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