Re: Function decorator that caches function results

2005-10-12 Thread Tom Anderson
On Tue, 10 Oct 2005, it was written: Tom Anderson [EMAIL PROTECTED] writes: Okay, a crack at a definition: a closure is a function in which some of the variable names refer to variables outside the function. That's misleading, You're right. I don't think it's wrong, but it depends on the

Re: Function decorator that caches function results

2005-10-11 Thread Piet van Oostrum
Paul Rubin http://[EMAIL PROTECTED] (PR) wrote: PR Tom Anderson [EMAIL PROTECTED] writes: PR That's misleading, I'd say a closure is a combination of a function PR (executable code) and a lexical environment [snip] PR This is all described in SICP (mitpress.mit.edu/sicp). Where the word

Re: Function decorator that caches function results

2005-10-11 Thread Fredrik Lundh
Tom Anderson wrote: Okay, a crack at a definition: a closure is a function in which some of the variable names refer to variables outside the function. And i don't mean global variables - i mean somebody else's locals; call them 'remote variables'. in Python, the global variables are someone

Re: Function decorator that caches function results

2005-10-10 Thread Tom Anderson
On Mon, 10 Oct 2005, Steven D'Aprano wrote: On Sun, 09 Oct 2005 17:39:23 +0200, Fredrik Lundh wrote: only if you're obsessed with CPython implementation details. No. I'm obsessed with finding out what closures are, since nobody seems to have a good definition of them! On the contrary -

Re: Function decorator that caches function results

2005-10-10 Thread Paul Rubin
Tom Anderson [EMAIL PROTECTED] writes: Okay, a crack at a definition: a closure is a function in which some of the variable names refer to variables outside the function. That's misleading, I'd say a closure is a combination of a function (executable code) and a lexical environment (the values

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sat, 08 Oct 2005 15:20:12 +0200, Lasse Vågsæther Karlsen wrote: Ok, so I thought, how about creating a decorator that caches the function results and retrieves them from cache if possible, otherwise it calls the function and store the value in the cache for the next invokation

Re: Function decorator that caches function results

2005-10-09 Thread Paul Rubin
Steven D'Aprano [EMAIL PROTECTED] writes: def cache_function(fn): cache = {} def cached_result(*args, **kwargs): if args in cache: return cache[args] result = fn(*args, **kwargs) cache[args] = result return result

Re: Function decorator that caches function results

2005-10-09 Thread Diez B. Roggisch
def cache_function(fn): cache = {} def cached_result(*args, **kwargs): if args in cache: return cache[args] result = fn(*args, **kwargs) cache[args] = result return result return cached_result I'm curious... where does cache live

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 02:49:38 -0700, Paul Rubin wrote: I'm curious... where does cache live after you use cache_function to memoize some function? It doesn't appear to be an attribute of the newly memoized function, nor does it look like a global variable. It's in the closure returned by

Re: Function decorator that caches function results

2005-10-09 Thread Fredrik Lundh
Steven D'Aprano wrote: I notice that type(some_closure) and type(ordinary_function) both return the same result, type 'function'. I also notice that both the closure and ordinary functions have an attribute func_closure. Is there a way to tell which is a closure and which is not? In my tests,

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 13:43:38 +0200, Fredrik Lundh wrote: Steven D'Aprano wrote: I notice that type(some_closure) and type(ordinary_function) both return the same result, type 'function'. I also notice that both the closure and ordinary functions have an attribute func_closure. Is there a

Re: Function decorator that caches function results

2005-10-09 Thread Diez B. Roggisch
If you create a closure, using a memoization technique as per the original post, and then call type() on that closure, Python reports type 'function'. Because it is. The closure is only sort of an extension to the locals() available to that function. Not more, not less. If you use dir() on

Re: Function decorator that caches function results

2005-10-09 Thread Fredrik Lundh
Steven D'Aprano wrote: Yes I did. Did you read my post? given that the wikipedia page says a closure is an abstraction representing a function, plus the lexical environment (see static scoping) in which the function was created. and you're still focussing on type(function), it

Re: Function decorator that caches function results

2005-10-09 Thread Ron Adam
Steven D'Aprano wrote: On Sat, 08 Oct 2005 15:20:12 +0200, Lasse Vågsæther Karlsen wrote: Ok, so I thought, how about creating a decorator that caches the function results and retrieves them from cache if possible, otherwise it calls the function and store the value in the cache

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 14:27:32 +0200, Fredrik Lundh wrote: Steven D'Aprano wrote: Yes I did. Did you read my post? given that the wikipedia page says a closure is an abstraction representing a function, plus the lexical environment (see static scoping) in which the function

Re: Function decorator that caches function results

2005-10-09 Thread Fredrik Lundh
Ron Adam wrote: In effect, 'cache' and 'fn' are replaced by the objects they reference before the cached_result function is returned. not really; accesses to free variables always go via special cell objects (rather than direct object references), and the compiler uses special byte codes for

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 13:43:38 +0200, Fredrik Lundh wrote: If I wanted to inspect the value of cache, where would I find it? nowhere. at least no officially; see Rebinding names in enclosing scopes in the design document for a discussion: http://www.python.org/peps/pep-0227.html

Re: Function decorator that caches function results

2005-10-09 Thread Fredrik Lundh
Steven D'Aprano wrote: let's take it again, with emphasis on some important words: a closure is an ABSTRACTION representing a function, PLUS the lexical ENVIRONMENT (see static scoping) in which the function was created. If you create a closure, using a memoization

Re: Function decorator that caches function results

2005-10-09 Thread Diez B. Roggisch
Clearly there is no DISTINCT closure object. If there were, I wouldn't need to ask how one can tell them apart, because type() would just report that one was a function and one was a closure. I don't have a problem with that. But read on... function objects always con- tain all the

Re: Function decorator that caches function results

2005-10-09 Thread Fredrik Lundh
Steven D'Aprano wrote: Each def or lambda expression that is executed will create a closure if the body of the function or any contained function has free variables. Presumably that means that if there are no free variables, no closure is created. you're quoting selectively; the word

Re: Function decorator that caches function results

2005-10-09 Thread Ron Adam
Fredrik Lundh wrote: Ron Adam wrote: In effect, 'cache' and 'fn' are replaced by the objects they reference before the cached_result function is returned. not really; accesses to free variables always go via special cell objects (rather than direct object references), and the compiler

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 18:00:13 +0200, Fredrik Lundh wrote: Steven D'Aprano wrote: Each def or lambda expression that is executed will create a closure if the body of the function or any contained function has free variables. Presumably that means that if there are no free variables, no

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 17:55:16 +0200, Diez B. Roggisch wrote: If what you say is true, then all functions are closures, and closure is just a synonym for function, and there is no difference between a function and a closure. Then why bother to create the term? Clearly, whoever invented the term

Re: Function decorator that caches function results

2005-10-09 Thread Steven D'Aprano
On Sun, 09 Oct 2005 17:39:23 +0200, Fredrik Lundh wrote: only if you're obsessed with CPython implementation details. No. I'm obsessed with finding out what closures are, since nobody seems to have a good definition of them! However, I have learnt some things: closures are something which

Re: Function decorator that caches function results

2005-10-09 Thread Piet van Oostrum
Steven D'Aprano [EMAIL PROTECTED] (SD) wrote: SD [penny drops] Now we're getting somewhere... a closure is something SD _added_ to a function. So we should talk about functions-without-closures SD and functions-with-closures. Well, I have never heard that definition. For more than half of my

Re: Function decorator that caches function results

2005-10-09 Thread Paul Rubin
Steven D'Aprano [EMAIL PROTECTED] writes: No. I'm obsessed with finding out what closures are, since nobody seems to have a good definition of them! Why don't you read SICP: http://mitpress.mit.edu/sicp/full-text/book/book.html You will be a much wiser person for having done so. However,

Re: Function decorator that caches function results

2005-10-09 Thread Paul Rubin
Steven D'Aprano [EMAIL PROTECTED] writes: Is it correct to say that Python *always* creates a closure whenever a def or lambda is executed? Or is it only for *certain* defs/lambdas? The word closure is being used two different ways. First of all the computer-science term closure which means a

Re: Function decorator that caches function results

2005-10-09 Thread Diez B. Roggisch
[penny drops] Now we're getting somewhere... a closure is something _added_ to a function. So we should talk about functions-without-closures and functions-with-closures. Yes. Speaking in terms of is a could be seen as some inheritance relation. [penny rises again] Dammit, just

Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
implementation instead of unwinding the recursive calls to avoid big exponential running-times. Ok, so I thought, how about creating a decorator that caches the function results and retrieves them from cache if possible, otherwise it calls the function and store the value in the cache for the next

Re: Function decorator that caches function results

2005-10-08 Thread Duncan Booth
Lasse Vågsæther Karlsen wrote: However, this: for index in range(1, 101): print index, fibonacci(idx = index) this one uses the kwargs list of arguments, and I'm not sure how to change my function to take that into account. Does anyone have any clues as to how to do that? The

Re: Function decorator that caches function results

2005-10-08 Thread jepler
On Sat, Oct 08, 2005 at 01:53:28PM +, Duncan Booth wrote: Unless the results stored in the cache are very large data structures, I would suggest that you simply store (args,kwargs) as the cache key and accept the hit that sometime you'll cache the same call multiple times. ... except

Re: Function decorator that caches function results

2005-10-08 Thread Sam Pointon
What about not storing args at all? Something like this: def cache_function(func, args_list): cache = {} def cached_result(*args, **kwargs): kwargs.update(dict(zip(args_list, args))) if kwargs in cache: return cache[kwargs] result = func(**kwargs)

Re: Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
[EMAIL PROTECTED] wrote: On Sat, Oct 08, 2005 at 01:53:28PM +, Duncan Booth wrote: Unless the results stored in the cache are very large data structures, I would suggest that you simply store (args,kwargs) as the cache key and accept the hit that sometime you'll cache the same call

Re: Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
Sam Pointon wrote: What about not storing args at all? Something like this: def cache_function(func, args_list): cache = {} def cached_result(*args, **kwargs): kwargs.update(dict(zip(args_list, args))) if kwargs in cache: return cache[kwargs]

Re: Function decorator that caches function results

2005-10-08 Thread Fredrik Lundh
Lasse Vågsæther Karlsen wrote: Yeah, but as far as I can see it, this one too fails to recognize situations where the function is called twice with essentially the same values, except that in one call it uses named arguments: k1 = fibonacci(100) k2 = fibonacci(idx = 100) this is

Re: Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
Lasse Vågsæther Karlsen wrote: Sam Pointon wrote: What about not storing args at all? Something like this: snip Ok, here's my updated version: class cache(object): def __init__(self, timeout=0): self.timeout = timeout self.cache = {} def __call__(self, fn):

Re: Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
Fredrik Lundh wrote: snip k1 = fibonacci(100) k2 = fibonacci(idx = 100) snip whoever writes code like that deserves to be punished. I'd say this thread points to a misunderstanding of what keyword arguments are, and how they should be used. the basic rule is that you shouldn't mix and

Re: Function decorator that caches function results

2005-10-08 Thread George Sakkis
Lasse Vågsæther Karlsen [EMAIL PROTECTED] wrote: [snip] Ok, so I thought, how about creating a decorator that caches the function results and retrieves them from cache if possible, otherwise it calls the function and store the value in the cache for the next invokation. [snip] Cool, you

Re: Function decorator that caches function results

2005-10-08 Thread Lasse Vågsæther Karlsen
George Sakkis wrote: snip Cool, you re-invented the memoization pattern: http://en.wikipedia.org/wiki/Memoization http://aspn.activestate.com/ASPN/search?query=memoizex=0y=0section=PYTHONCKBKtype=Subsection Yes, it's kinda discouraging that most interesting ideas have already been