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 <juan.faco...@gmail.com>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 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 > -- 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