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

Reply via email to