On Mon, 24 Mar 2003 03:42:06 +0900 Paul Prescod <paul / prescod.net> wrote: > Joel VanderWerf wrote: > > ... > > > > But in Python, the inner function only has access to the _object_, not > > to the original variable which refers to the object, and so you have to > > "box" the value inside an object if you want to have shared references. > > No, you still don't undestand the issue properly. You're getting closer, > but not quite there yet. > > y = 0 > > def foo(): > global y > x = 0 > def bar(): > print x, y > bar() > x = y = 1 > bar() > x = y = 2 > bar() > x = y = 3 > bar() > x = y = 4 > bar() > x = y = 5 > > foo() > > 0 0 > 1 1 > 2 2 > 3 3 > 4 4 > > Now just as in Ruby, 0, 1, 2, 3, 4 are separate objects. It is literally > impossible to change their values. All you can do is change bindings TO > the variables. So obviously "bar" is really inheriting the _bindings_ > for x and y because it is the _bindings_ that are changing. > > So what's the problem? Consider this program: > > y = 0 > > def foo(): > x = 0 > def bar(): > print x, y > def change(z): > global y > x = y = z > > change(1) > bar() > change(2) > bar() > change(3) > bar() > change(4) > bar() > > foo() > > The output is: > > 0 1 > 0 2 > 0 3 > 0 4 > > This is because Python has always adopted the rule that if you assign to > a local variable it springs into existence -- as a local. If you want to > overwrite a global variable, you have to specifically say: "please > overwrite this global." It prevents people from accidentally overwriting > globals with locals. > > But there is no syntax for saying: "please overwrite this intermediate > closure variable." It would be as easy as adding a keyword > "intermediate" or "closure". It's purely a syntactic issue. > > _But_ the addition would be useless in practice because this problem > almost never arises in real code. Its only purpose would be to answer > Lisp and Ruby advocates who want to say that Python doesn't really have > closures. I don't know whether Guido will ever add it for, er, closure, > but I do know that I have _never_ _once_ needed this keyword in hundreds > of thousands of lines of real Python code I have written. And I am thus > going to fight my temptation to go and bug Guido to do it so that we can > put an end to permathreads about Python's lack of closures. ;) If this > problem ever arose in my code (which it has not) then I could work > around it thus: > > y = 0 > > def foo(): > x = [0] > def bar(): > print x[0], y > def change(z): > global y > x[0] = y = z > > change(1) > bar() > change(2) > bar() > change(3) > bar() > change(4) > bar() > > foo() > > 1 1 > 2 2 > 3 3 > 4 4 > > This should prove that the problem is really not deep in the Python > interpreter or anything like that. It would be a half day's work to > write the patch that added the "intermediate" keyword. > > By the way, there was a time when Python really did lack closures but > there was a hacky workaround. This is where the idea that Python did not > have "real" closures became popular (because it was true). Then Python > added closures, but left out one minor feature and the minor feature > allowed the idea to persist even when it had ceased to be true. This is true. Some distros still ship an older version of Python without the closures feature. I don't think anyone really cares about the more esoteric issue described here. > > Paul Prescod > > >