On Wed, Jul 13, 2011 at 10:33 AM, Andrea Tortorella 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