To my knowledge, you can't do that kind of thing without interfering with either the definition of the function you're wrapping, or with how the language invokes functions -- either way, you're looking at a huge hack if you want to do this at runtime.
Python has decorators which can do what you want fairly cleanly, but they require modifying the wrapped function to indicate that it is wrapped. They'd look something like this (untested):
# Maps functions to arguments to results of calling functions with those arguments
previousResults = {}
def memoize(function):
# Establish an entry in our memo map for this function.
global previousResults
if function not in previousResults:
previousResults[function] = {}
def wrappedFunc(*args):
# Check if we've tried this before.
key = tuple(args)
if key in previousResults[function]:
return previousResults[function][key]
value = function(*args)
previousResults[function][key] = value
return value
return wrappedFunc
@memoize
def fib(n):
if n == 0:
return 0
if n <= 2:
return 1
return fib(n - 1) + fib(n - 2)
Thus, you can't at runtime say "Hang on, I want to decorate this function so it's memoized"; however, you can easily memoize any function by making a one-line change to it.
EDIT: more generally, you can do this kind of thing in any language that supports functions as first-class objects. Putting "@memoize" before the definition of fib() is just syntactic sugar for saying "def tmp(n): ...; fib = memoize(tmp)".