I think it has to do with the closure in the *fn *used when generating the 
form in the macro. 

If you change this function:

*(defn make-greeter []*
*  (let [message "hello"]*
*    (fn [user-name]*
*      (str message ", " user-name))))*

To this one:

*(defn make-greeter []
*
*  (fn [user-name]*
*    (let [message "**hello**"]*
*      (str message ", " user-name))))*

There's no closure on the *message* local var, so you don't get any errors 
when the form the macro produces is compiled.

*constantly** *also creates a closure on its argument:

*(defn constantly*
*  "Returns a function that takes any number of arguments and returns x."*
*  {:added "1.0"*
*   :static true}*
*  [x] (fn [& args] x))*

So the source of the problem seems to be the same.

Although I'm not completely sure why this doesn't work, I think it kind of 
makes sense since the *fn* returned by *make-greeter* is actually produced 
in the *defmacro* body and not in the form generated, somehow the closure 
is lost and the error is generated.

Someone with a better understanding of macros please jump in.

Juan

On Sunday, December 16, 2012 11:24:35 AM UTC-3, jarppe wrote:
>
> Hi,
>
> I have this macro (complete file https://www.refheap.com/paste/7633):
>
> *(*defmacro defgreeter [greeter-name]
>
>   *(*let [greeter *(*make-greeter*)*]
>
>     `*(*do
>
>        *(*defn ~greeter-name [user-name#]
>
>          *(*~greeter user-name#*)**)**)**)**)*
>
>
> It works as expected when make-greeter is defined like this:
>
> *(*defn make-greeter []
>
>   *(*fn [user-name]
>
>     *(*str "Hello, " user-name*)**)**)*
>
>
> I can use it like this:
>
> *(*defgreeter hello*)*
>
> *(*hello "jarppe"*)*
>
> How ever, if I change make-greeter to this I get IllegalArgumentException:
>
> *(*defn make-greeter []
>
>   *(*let [message "hello"]
>
>     *(*fn [user-name]
>
>       *(*str message ", " user-name*)**)**)**)*
>
>
> Interestingly, this does not work either:
>
> *(*defn make-greeter []
>
>   *(*constantly "what erver"*)**)*
>
> What am I missing?
>
> -- 
> -jarppe
>
>

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