<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, Jul 5, 2018 at 3:45 PM Nick Coghlan <<a href="mailto:ncoghlan@gmail.com">ncoghlan@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><br><br><div class="gmail_quote"><div dir="ltr">On Thu., 5 Jul. 2018, 3:17 pm Guido van Rossum, <<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>Let me be slightly contrarian. :-)<br></div><div dir="ltr"><br></div><div dir="ltr">On Wed, Jul 4, 2018 at 9:12 PM Chris Angelico <<a href="mailto:rosuav@gmail.com" rel="noreferrer" target="_blank">rosuav@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Definitely against augmentation, for several reasons:<br>
<br>
1) Spelling - should it be :+= or +:= ?<br></blockquote><div><br></div><div>That one's easy. As Nick's (withdrawn) PEP 577 shows it should be simply `+=`.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
2) Is the result of the expression the modified value or the original?<br></blockquote><div><br></div><div>Someone (sadly I forget who) showed, convincingly (to me anyways :-) that it should return whatever the `__iadd__` method returns, or (if there isn't one) the result of `a = a + b`.<br></div><div></div></div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">I think I had it as an open question in one of the earlier drafts of PEP 577.</div><div dir="auto"><br></div><div dir="auto">The subsequent rationale for it returning the modified value was that we have this existing equivalence at the statement level:</div><div dir="auto"><br></div><div dir="auto">    a += b</div><div dir="auto">    a = operator.iadd(a, b)</div><div dir="auto"><br></div><div dir="auto">So the natural expression level semantics would be:</div><div dir="auto"><br></div><div dir="auto"><span style="font-family:sans-serif">    a := operator.iadd(a, b)</span><br></div></div></blockquote><div><br></div><div>Thinking about it more, I think the real stumper was what should happen for either of these:</div><div><br></div><div>x = (a.b := 1)</div><div>x = (a.b += 1)</div><div><br></div><div>Take the first one and let's try to compile it to pseudo bytecode (which I'm making up on the spot but should be simple enough to understand if you've seen output from the "dis" module):<br></div><div><br></div><div>LOAD 1</div><div><div>LOAD a</div>SETATTR b</div><div>???<br></div><div><br></div><div>What do we do next? We could do</div><div><br></div><div>LOAD a</div><div>GETATTR b</div><div>STORE x</div><div><br></div><div>But this gives a's class the opportunity to change the value (because its __setattr__ could normalize the value, e.g. to a string or a float, and then its __getattribute__ would return the normalized value). But this seems a rare case and wastes time in the common case, and also seems somewhat more surprising than always assinging 1 to x regardless of what SETATTR did, so I'd rather forgo the extra GETATTR operation. So I think it should be<br></div><div><br></div><div>LOAD 1</div><div>DUP</div><div><div>LOAD a</div>SETATTR b</div><div>LOAD r1</div><div>STORE x</div><div><br></div><div>I think the second example could be translated as follows (using a register rather than a sequence of DUPs and ROTs to save the extra copy of the result of the IADD that we want to store into x).<br></div><div><br></div><div>LOAD a</div><div>DUP<br></div><div>GETATTR b</div><div><div>LOAD 1</div>IADD</div><div>COPY .r1  # copy into register r1<br></div><div>SETATTR b  # this uses the reference to a that was left on the stack by DUP</div><div>LOAD .r1<br></div><div>STORE x</div><div><br></div><div>I used pen and paper to figure out what was on the stack at each point and had to rewrite the pseudo bytecode several times. But now I'm pretty sure this will pose no serious challenge for bytecode generation.</div><div><br></div><div>But I'd like to point out to anyone who made it this far that this is not part of PEP 572! The PEP currently proposes neither "+=" in expressions nor targets that are attributes -- it only proposes "NAME := EXPR" because for the others the use cases are just too thin. (But in the past we said that about things like "(1, 2, *args, *more_args)" and eventually we found enough use cases for them that they were added. :-)<br></div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">--Guido van Rossum (<a href="http://python.org/~guido">python.org/~guido</a>)</div></div>