On 9/26/2011 10:24 AM, Paul Moore wrote:
I agree entirely. My point here wasn't to suggest that this needs a new keyword, but rather that the proposal uses an unnatural keyword to avoid needing a new keyword.
Your argument that this is a simple extension of the semantics of "nonlocal" is reasonable when viewing nonlocal in terms of lifetimes. My contention is that most people view nonlocal in terms of visibility (and in that view, the two uses of nonlocal are jarringly dissimilar).
In the template below, the visibility of VAR in _outer is both ephemeral (lasting only for one quick call) and non-essential (in that VAR is never *used* within _outer. Today's default value objects *are* visible non-locally:
def f(a=3): pass
f.__defaults__[0] 3
They optionally get bound to local names but they are *not* local values any more than cell values are. Lifetime and visibility are actually coupled. You cannot see something that does not exist; invisible objects tend to be garbage collected and cease to exist.
It may be easier to turn things around and specifically look at it from the "syntactic sugar" point of view:
# Current syntax
def _outer(): # Boilerplate VAR = EXPR def FUNC(): # Real function name is hidden nonlocal VAR # VAR repeated # Do stuff with VAR, including rebinding it return f # Boilerplate FUNC = _outer() # Boilerplate and FUNC repeated
Most of that code is noise: the interesting aspects are that: 1. There is a function called FUNC() available for use 2. VAR survives across invocations of FUNC() 3. At the first invocation of FUNC(), the initial value of VAR will be EXPR
So, let's offer a syntax that just includes those 3 pieces of interesting information without the boilerplate:
def FUNC(): # Function of interest is not hidden in a nested scope nonlocal VAR from EXPR # Shared variable and initial value # Do stuff with VAR
-- Terry Jan Reedy