def curry(*args, **kwargs): def _curried(*moreargs, **morekwargs): return args[0](*(args[1:]+moreargs), **dict(kwargs.items() + morekwargs.items())) return _curried class Promise: """ This is just a base class for the proxy class created in the closure of the lazy function. It can be used to recognize promises in code. """ pass def lazy(func, *resultclasses): """ Turns any callable into a lazy evaluated callable. You need to give result classes or types -- at least one is needed so that the automatic forcing of the lazy evaluation code is triggered. Results are not memoized; the function is evaluated on every access. """ class __proxy__(Promise): # This inner class encapsulates the code that should be evaluated # lazily. On calling of one of the magic methods it will force # the evaluation and store the result. Afterwards, the result # is delivered directly. So the result is memoized. def __init__(self, args, kw): self.__func = func self.__args = args self.__kw = kw self.__dispatch = {} for resultclass in resultclasses: self.__dispatch[resultclass] = {} for (k, v) in resultclass.__dict__.items(): setattr(self, k, self.__promise__(resultclass, k, v)) def __promise__(self, klass, funcname, func): # Builds a wrapper around some magic method and registers that magic # method for the given type and method name. def __wrapper__(*args, **kw): # Automatically triggers the evaluation of a lazy value and # applies the given magic method of the result type. res = self.__func(*self.__args, **self.__kw) return self.__dispatch[type(res)][funcname](res, *args, **kw) if not self.__dispatch.has_key(klass): self.__dispatch[klass] = {} self.__dispatch[klass][funcname] = func return __wrapper__ def __wrapper__(*args, **kw): # Creates the proxy object, instead of the actual value. return __proxy__(args, kw) return __wrapper__