On May 1, 4:42 pm, André Thieme <splendidl...@googlemail.com> wrote: > I am currently writing a neat logging lib and want it to support dynamic > and static logging. When I activate (static-logging!) then the log macro > (log :warn "message") will check during macro expansion time which log > level is currently set and decides based on that if code will be > generated that logs the message or not. > > The user can set any log function and for that purpose I offer some > closure factories, such as make-writer-logger or make-file-logger. > Two useful writer-loggers are defined as: > (def out-logger (make-writer-logger *out*)) > (def err-logger (make-writer-logger *err*)) > > The make-writer-logger returns a closure that takes a level and a > message and writes this to the given Writer. Now my current logger is > stored in an atom, for example the default is > (let [logger (atom out-logger)] …) > Inside my log macro I want to call @logger, which unfortunately results > in an Exception: > “No matching ctor found for class my.logger$make_writer_logger$fn__1588” > > Please try this minimal example in your REPL: > (defn f [x] (fn [] x)) ; the closure factory > (def foo (f 0)) ; a useful instance > (defmacro bar [] `(let [a# ~foo])) > and then call (bar) > > As soon f doesn’t return a closure but just a fn, then this Exception > is not thrown, but instead the code works. > > Just from looking at the macro definition I would say it should work for > any object as long foo is defined. > > Is that behaviour a bug? How easy is it to fix it? > Are there any work-arounds?
You can't embed a function in code as a raw function object - you need to return code that will result in that function. That it happens to work for non-closure functions is, as I understand it, a happy (or not?) accident. The "workaround" is simple enough: don't do it. Instead, return code that will be evaluated in the expansion context and have the effect you want. user> (defmacro bar [[name] & body] `(let [~name (f 0)] ~@body)) #'user/bar user> (bar [log] (log)) 0 -- 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