On Wed, Jul 13, 2011 at 10:33 AM, Andrea Tortorella <elian...@gmail.com> wrote: > I'm not an expert in macros, and maybe this is a stupid question but i > think there should be a general pattern for this. > > I' ve a function: > > (defn choose* [f & choices] > "Applies f to one of the choices" > ..... .....) > > And this macro: > > (defmacro choose [[c choices] & body] > `(choose* (fn [~c] ~@body) ~@choices)) > > Now if i call it with a literal sequence: > > (choose [x [:a :b :c]] > (println x)) > > it correctly expands to: > > (choose* (fn [x] (println x)) :a :b :c) > > but if i have: > > (def y [:a :b :c]) > (choose [x y] > (println x)) > > it gives me an error: don't know how to create ISeq from symbol. > > with an expression: > > (choose [x (vec 2 3 4)] > (println x)) > > it expands to: > > (choose* (fn [x] (println x)) vec 2 3 4) > > I knew it could not be that simple, and i also understand why i get > theese expansions, but i don't get how to solve it. > So what's the pattern for something like this, where you want to > evaluate a symbol or an expression before expansion? > > Andrea
Macros splice in an unevaluated expression. You'll get what you want if you change the definition of choose* to: (defn choose* [f choices] "Applies f to one of the choices" ..... .....) so it takes a function and a sequence argument, rather than a function and a variable number of element arguments, and of choose to: (defmacro choose [[c choices] & body] `(choose* (fn [~c] ~@body) ~choices)) so it doesn't splice choices. Your last example (choose [x (vec 2 3 4)] (println x)) should now expand to: (choose* (fn [x] (println x)) (vec 2 3 4)) which means the new choose* will run with choices bound to the vector [2 3 4] as you desired. -- Protege: What is this seething mass of parentheses?! Master: Your father's Lisp REPL. This is the language of a true hacker. Not as clumsy or random as C++; a language for a more civilized age. -- 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