On 20 July 2010 23:41, Moritz Ulrich <ulrich.mor...@googlemail.com> wrote:
> I think the tour problem is the (def m-fib (memoize fib)). You create
> a new memoized function m-fib, while fib will internally call the
> non-memoized fib. You have to do something like: (binding [fib
> (memoize fib)] (fib 42)).
> However, this will break if you use recur instead of recursive calls to fib.

Actually self-calls don't go through Vars, so the binding changes
nothing. Try this if you want to check it for yourself:

user=> (defn foo [x] (Thread/sleep 100) (if (zero? x) :done (foo (dec
x))))
#'user/foo
user=> (binding [foo (memoize foo)] (println (foo 10)) (println (foo
10)) (println (foo 9)))
:done ; after a delay
:done ; immediately afterwards
:done ; after another delay
nil

To force the self-call to go through the Var, you could use #'foo in
place of foo:

(defn foo [x] (Thread/sleep 100) (if (zero? x) :done (#'foo (dec x))))

If you try the above (binding ...) form with this version, you'll
notice there's no delay before the final printout.

This has a cost of its own and requires a change to the function's
code, so might not always be a good idea. It's simpler than baking a
local cache into the function itself, though; and if you've got a
self-recursive function foo written in this fashion, you can do

(alter-var-root #'foo memoize)

to memoize it "in place". (If you need the original function, you
could put it in the Var's metadata; and if at some point metadata on
functions becomes officially supported -- as opposed to being an
experimental feature -- maybe memoize could put the original function
in the memoized function's metadata.)

Sincerely,
Michał

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