Hi Roman, as far as I understand, the Clojure compiler is doing some optimizations for recursive functions to save the variable lookup. This means that you have to explicitly write the recursive call as (#'fact (dec n)) if you want to dynamically rebind the function. Somehow this doesn't feel right for a dynamic language.
Clojure 1.3, which cannot dynamically rebind variables unless they are explicitly marked as ^:dynamic, introduced with-redefs to solve this problem. In Clojure 1.3 you're example works as expected if you use with-redefs instead of binding in the definition of fact-with-logging. In case you can't use Clojure 1.3, you might be able to use the source code of with-redefs in order to achieve a similar effect in 1.2. Though, I haven't tested it. Best, Nils On Nov 30, 9:11 pm, Roman Perepelitsa <roman.perepeli...@gmail.com> wrote: > Hello, > > I'm trying to intercept each call to a recursive function in order to > insert logging. It works on the first invocation but not on others. What am > I missing? > > (defn fact [n] > (if (< n 2) > 1 > (* n (fact (dec n))))) > > ; Given function f, returns another function that > ; does the same as f but also prints the arguments. > (defn with-logging [f] > (fn [& rest] > (do > (println (str rest)) > (apply f rest)))) > > ; Factorial that prints its argument on each call. > (defn fact-with-logging [n] > (binding [fact (with-logging fact)] (fact n))) > > ; This prints (5) but not (4)...(1). Why? > (fact-with-logging 5) > > Roman. -- 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