[Tutor] a caching function and argument passing

Daniel Yoo dyoo@hkn.EECS.Berkeley.EDU
Mon, 12 Jun 2000 00:26:33 -0700 (PDT)


After reading a little of Peter Norvig's "Paradigms of Artificial
Intelligence", I've been playing around with equivalent programs in
Python.  One of these include a "caching function generator", a general
program that caches the results of another:

def makeCachedFn(fn):
    cache = {}
    def newfn(arg, fn=fn, cache=cache):
        if not cache.has_key(arg):
            cache[arg] = fn(arg)
        return cache[arg]
    return newfn

As you can see, this will cache f(x), and works pretty well.  For example:

  def factorial(x):
    if x == 0: return 1
    else: return x * factorial(x-1)
  factorial = makeCachedFn(factorial)
 
does a very nice job in eliminating the cost of subsequent function
calls.

The problem I'm running into is in trying to generalize the generator for
functions with an arbitrary number of arguments.  I've tried to do
something like:

  def newfun(*args, fn=fn, cache=cache)

but in Python 1.52, this is an illegal signature, since optional
parameters go at the end.  I tried:

  def newfun(fn=fn, cache=cache, *args)

but that apparently doesn't work either, because default arguments have
priority in getting assigned first.  Basically, I've been using the
default arguments to simulate closures, but it's not quite working.

Any help on this would be greatly appreciated.  Thank you!