Function decorator that caches function results

Diez B. Roggisch deets at nospam.web.de
Sun Oct 9 11:55:16 EDT 2005


> 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 information they need about their context, and the sum of that is
>>what forms the closure.
> 
> 
> 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 did so to distinguish the two.

You seem to still not getting to it: they aren't supposed to be 
distinguished - a function is a function. But it _can_ have a closure, 
which (shortly spoken) enriches it's local variables lookup. Speaking in 
terms of "is a" could be seen as some inheritance relation. Which 
functions and functions with a closure _could_ have if one wanted to. 
But that is true for other OO-concepts two. See below.

> At a practical, Python level, there is a difference between a function
> before and after it gets made into a closure using, e.g. the original
> poster's memoization technique. In Python at least, it is not true that a
> function and a function-turned-into-closure is the same thing.
> 
> See, for example, this:-


<snip>

Nope. You mix things here. spam1 is a function. spam2 is actually bound 
to the function-object created by do_nothing - a function that has a 
closure because it is nested in closefy, and accesses variables from its 
outer lexical scope - thus i needs a closure. Part of do_nothing's 
closure is spam1 (or, better to say, the function reference that has 
been originally bound to spam1 - spam1 is just a name). Important is 
that the closure gets created at runtime, so each returned instance of 
do_nothing has its own. But the original spam1 implementation is 
untouched  contrary to what  you state above. It still is teh same 
thing, and has no closure.

Consider this:

class Foo(object):
     pass

f = Foo()
g = Foo()
g.bar = "whatever"

f and g are both Foo - but one has a different attribute set. And if Foo 
had some semantics that did something different based on bar, would you 
also say they're supposed have two different classes? You could in fact 
do that - create one class for each incarnation of possible  state. But 
then the concept of classes and objects gets somewhat blurred, as each 
instance would have its own class. The same is true for functions.

> So no, there is no "abstract" difference between a closure and a raw
> function, but there is a practical difference. Now perhaps in some other
> languages there is no practical difference either, but (as far as I can
> see) Python is not that language.
> 
> Am I close? 

Closer :)

Regards,

Diez



More information about the Python-list mailing list