[Python-Dev] PEP 572 semantics: all capabilities of the assignment statement (original) (raw)
Guido van Rossum guido at python.org
Thu Jul 5 19:46:45 EDT 2018
- Previous message (by thread): [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement
- Next message (by thread): [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Thu, Jul 5, 2018 at 3:45 PM Nick Coghlan <ncoghlan at gmail.com> wrote:
On Thu., 5 Jul. 2018, 3:17 pm Guido van Rossum, <guido at python.org> wrote: Let me be slightly contrarian. :-)
On Wed, Jul 4, 2018 at 9:12 PM Chris Angelico <rosuav at gmail.com> wrote:
Definitely against augmentation, for several reasons:
1) Spelling - should it be :+= or +:= ?
That one's easy. As Nick's (withdrawn) PEP 577 shows it should be simply
+=
. 2) Is the result of the expression the modified value or the original? 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 ofa = a + b
. I think I had it as an open question in one of the earlier drafts of PEP 577. The subsequent rationale for it returning the modified value was that we have this existing equivalence at the statement level: a += b a = operator.iadd(a, b) So the natural expression level semantics would be: a := operator.iadd(a, b)
Thinking about it more, I think the real stumper was what should happen for either of these:
x = (a.b := 1) x = (a.b += 1)
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):
LOAD 1 LOAD a SETATTR b ???
What do we do next? We could do
LOAD a GETATTR b STORE x
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
LOAD 1 DUP LOAD a SETATTR b LOAD r1 STORE x
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).
LOAD a DUP GETATTR b LOAD 1 IADD COPY .r1 # copy into register r1 SETATTR b # this uses the reference to a that was left on the stack by DUP LOAD .r1 STORE x
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.
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. :-)
-- --Guido van Rossum (python.org/~guido) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20180705/372afd62/attachment-0001.html>
- Previous message (by thread): [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement
- Next message (by thread): [Python-Dev] PEP 572 semantics: all capabilities of the assignment statement
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]