Expanding symbols and expression in macros.

2011-07-13 Thread Andrea Tortorella
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

-- 
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


Re: Expanding symbols and expression in macros.

2011-07-13 Thread Luc Prefontaine
(defmacro choose [[c choices]  body]
  `(choose* (fn [~c] ~@body) ~choices)) --- not ~@, just ~

~@ expects a sequence result
In your first example, [:a :b :c] is a sequence but in the second example, y is 
not.

body is a sequence ( body), using ~@ there is ok there.

Luc P.

On Wed, 13 Jul 2011 07:33:57 -0700 (PDT)
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
 



-- 
Luc P.


The rabid Muppet

-- 
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


Re: Expanding symbols and expression in macros.

2011-07-13 Thread Ken Wesson
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