<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 15 May 2018 at 01:53, Tim Peters <span dir="ltr"><<a href="mailto:tim.peters@gmail.com" target="_blank">tim.peters@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">[Nick]<span class="gmail-"><br></span><div><span class="gmail-">
> The question would then turn to "What if you just want to bind the target<br>
> name, without considering the old value?". And then *that's* where "NAME : =<br>
> EXPR" would come in: as an augmented assignment operator that used augmented<br>
> assignment scoping semantics, rather than regular local name binding<br>
> semantics.<br>
<br>
</span>Plain old ":=" would somehow be viewed as being an augmented<br>
assignment operator too? ... OK, the meaning is that augmented<br>
assignment _and_ ":=" would resolve the target's scope in the way the<br>
containing block resolves it.<br>
<span class="gmail-">
<br>
> That would mean *directly* overturning PEP 3099's rejection of the idea of<br>
> using "NAME := EXPR" to imply "nonlocal NAME" at function scope, but that's<br>
> effectively on the table for implicit functions anyway (and I'd prefer to<br>
> have ":=" be consistent everywhere, rather than having to special case the<br>
> implicit scopes).<br>
<br>
</span>Creating a local in a containing scope by magic is never done by<br>
Python today. Extending that beyond "need" seems potentially<br>
perilous. For example, it can already be tedious to figure out which<br>
names _are_ local to a function by staring at the function's code, but<br>
people quickly get better at that over time; change the rules so that<br>
they _also_ have to stare at all immediately contained functions too<br>
to figure it out, and it may become significantly harder (OK, I didn't<br>
declare `x`, and a contained function did `x := 3.14` but `x` isn't<br>
declared there either - I guess it's my `x` now). Then again, if<br>
they're doing that much function nesting they deserve whatever they<br>
get ;-)<br></div></blockquote><div><br></div><div>More likely they'd get a compile time error complaining that the compiler couldn't figure out what they meant, and asking them to be clearer about the intended scoping.</div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
Restrict it to that only synthetically generated functions can pull<br>
off this trick by magic (where there are real use cases to motivate<br>
it), and they still don't have to look outside the body of a<br>
function's text to figure it out. Visually, there's no distinction<br>
between the code running in the function's scope and in scopes<br>
synthesized to implement comprehensions appearing in the function's<br>
text. The comprehensions aren't even indented more.<br>
<br>
So, offhand, I'm not sure that the right way to address something you<br>
view as a wart is to vastly expand its reach to 12 operators that<br>
impose it on everyone everywhere every time they're used ;-)<br></div></blockquote><div><br></div><div>Once I reframed the idea as being like an augmented assignment, your proposed semantics seemed a lot less magical to me, since I was able to define them in terms of "find the assignment or declaration that already exists", rather than implicitly creating a new one. If the compiler can't find a suitable target scope, then it can throw AmbiguousTargetError (which would be an improvement over the runtime UnboundLocalError you typically get today).<br></div><div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
Seriously, I do suspect that in<br>
<br>
def f(...):<br>
... no instances of `s` ...<br>
s += f"START {time.time():.2f}"<br>
<br>
it's overwhelmingly more likely that they simply forgot to do<br>
<br>
s = ""<br>
<br>
earlier in `f` than they actually wanted to append to whatever `s`<br>
means in f's parent block.. That's a radical change to what people<br>
have come to expect `NAME +=` to do.<br></div></blockquote><div><br></div><div>I think this is the key argument in favour of only allowing the "implicitly nonlocal rebinding" behaviour in lambda expressions, generator expressions, and comprehensions, as that way the search for a target to bind would always terminate at the containing block (just as it does today).<br></div><div></div><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
BTW, would<br>
<br>
def f():<br>
x := 3.14<br>
x = 3.14<br>
<br>
be a compile-time error? Everyone agreed the analogous case would be<br>
in synthetic functions. Fine by me!<br>
</div></blockquote></div><br></div><div class="gmail_extra">Yeah, I think that would be an AmbiguousTargetError, as when the compiler saw "x := 3.14", it wouldn't have seen "x = 3.14" yet.<br><br></div><div class="gmail_extra">For other augmented assignments, it would be a DeprecationWarning for the time being, and become an AmbiguousTargetError at a later date.<br><br> (This also relates to the previous point: if "x := 3.14" can be
implicitly nonlocal, then I couldn't answer that question without knowing which names were defined in outer scopes. By contrast, if the implicit access to outer scopes is limited to inline scopes accessing their containing scope, then this example becomes precisely analagous to the current syntax error for binding a name as a local before declaring it as global or nonlocal. The statement of ambiguity would arise from the fact that when we see "TARGET := EXPR" at statement level, we don't know if the missing prior statement is a local variable assignment, a type declaration, or a global or nonlocal declaration)<br><br></div><div class="gmail_extra">Cheers,<br></div><div class="gmail_extra">Nick.<br></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature" data-smartmail="gmail_signature">Nick Coghlan | <a href="mailto:ncoghlan@gmail.com" target="_blank">ncoghlan@gmail.com</a> | Brisbane, Australia</div>
</div></div>