[Tim] > ... > Here's an example where I don't know what the consequences of "the > rules" should be: > > def f(): > a = 10 > local a: > def showa(): > print("a is", a) > showa() # 10 > a = 20 > showa() # 20 > a = 30 > showa() # 10 > > The comments show what the output would be under the "nothing about > scope rules change" meaning. They're all obvious (since there is is > no new scope then - it's all function-local). > > But under the other meaning ...? > > The twist here is that `def` is an executable statement in Python, and > is a "binding site" for the name of the function being defined. So > despite that `showa` appears to be defined in a new nested lexical > scope, it's _actually_ bound as a function-local name. That's bound > to be surprising to people from other languages: "I defined it in a > nested lexical scope, but the name is still visible after that scope > ends?". > > I don't know what the first `showa()` is intended to do. Presumably > `a` is unbound at the start of the new nested scope? So raises > NameError? If so, comment that line out so we can make progress ;-) > > It seems clear that the second `showa()` will display 20 under any reading. > > But the third? Now we're out of the `local a:` scope, but call a > function whose textual definition was inside that scope. What does > `showa()` do now to find a's value? f's local `a` had nothing to do > with the `a` in the nested scope, so presumably it shouldn't display > 10 now. What should it do? > Does the final state of the nested scope's locals need to preserved so > that showa() can display 30 instead? Or ...?
Just noting that a sane way to answer such questions is to model the intent with nested functions in current Python. It's annoying because you have to explicitly declare the _non_-local names instead, and also make dummy assignments to those names to tell Python in which scope they _should_ be bound. So, e.g., for the above you can write this: def f(): a = 10 # Have to give `showa` _some_ binding in its intended scope, # else the "nonlocal showa" below is a compile-time error showa = None def local_a(): nonlocal showa def showa(): print("a", a) #showa() # raises NameError a = 20 showa() # 20 a = 30 local_a() del local_a showa() # 30 print("but f's a is", a) # 10 The comments show what happens when you call `f()`, matching the guesses in the original message. One thing to note: if this does model the intent, it's essentially proof that it's implementable without intractable effort; e.g., the machinery needed to implement funky closures already exists. But another: since I've never seen code anything like this before, that casts doubt on whether the semantics are actually useful in real life. That's why I always ask for real use cases ;-) _______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/