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 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.
[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. > Speaking in > terms of "is a" could be seen as some inheritance relation. [penny rises again] Dammit, just when I thought I got it. So a closure is like a subclass of function? Functions are a higher level classification, like mammals. There are mammals that are primates (functions that _are_ closures) and mammals that aren't (functions that _aren't_ closures). > 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. Yes. > spam2 is actually bound > to the function-object created by do_nothing - Yes. > 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. Right! So closures are something which functions _have_ -- which is why Python functions have an attribute called func_closure, which is empty in functions without closures, and contain a tuple of cells in those with them. Now somebody is going to tell me this is an implementation detail and it isn't true in the general language independent case... > 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). Yes, I can see that. > 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 Now you're trying to trick me... they are both *instances* of Foo, not Foo. Foo is a class, and f and g are not classes, let alone the same class. > - 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. Ah, but in languages like Pascal that can take functions as arguments, but can't return functions as output, *all* functions have to be created separately. To take your analogy and run with it, Pascal would be like a language that didn't allow f and g to have different attributes unless they belonged to different classes. Python is not like that, which is why you can write a function to return functions (a factory function?). If the output function needs access to the namespace of the factory function, Python adds a closure to that output function, giving it access to the objects in that namespace. -- Steven. -- http://mail.python.org/mailman/listinfo/python-list