I don't know why it doesn't work. However, changing defgreeter to the
following seems work.
(defmacro defgreeter [greeter-name]
(let [greeter (make-greeter)]
`(def ~greeter-name ~greeter)))
Might be a clue. :)
Jonathan
On Sun, Dec 16, 2012 at 6:49 PM, juan.facorro <[email protected]>wrote:
> 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<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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en