[Python-Dev] PEP 572: Assignment Expressions

Tim Peters tim.peters at gmail.com
Tue Apr 17 18:23:13 EDT 2018


[Tim]
>> I'll channel that Guido would be happiest if this rule were followed:
>>
>> Given an assignment statement using "=", the meaning is the same if
>> "=" is replaced with ":=".

[Chris]
> That's broadly the intention. At the moment, there are two exceptions:
>
> 1) Augmented assignment isn't a thing

Doesn't have to be :-)  "Augmented assignment statement" is already a
different thing than "assignment statement" (for example, in an
augmented assignment statement, there is no chaining, and the sole
target can' t be, e.g., a slice or any form of unpacking syntax).


> 2) Chained assignment isn't a thing, which means that the assignments
> operate right-to-left

>> In particular, the expression at the far right is evaluated once, and
>> - in case of chained assignments - is applied in turn to each target
>> left-to-right.

> I'll toy with this and see if I can implement it sanely. If so,
> that'll eliminate one more distinction.

>> Otherwise the semantics of "=" and ":=" can be very different indeed.

> TBH, the common cases won't actually be much affected.

Or at all!  That's not the point here, though:  if making assignment
expressions work as exactly like assignment statements as possible is
what's needed for the PEP to pass, it's the _annoying_ cases that have
to be looked at.

Personally, after considerable staring at my own code, I would be
perfectly happy to settle for assignment expressions no fancier than

    identifier ":=" expression

That alone covers over 99% of the cases I'd be tempted to use the new
feature at all, and then gobs of general-case assignment-statement
difficulties go away, including the "right-to-left or left-to-right?"
distinction (there's no way to tell which order bindings happen in `x
:= y := z := 3` short of staring at the generated code).

But so far I haven't gotten the impression that Guido is fond of that.
He should be, though ;-)


> You give this example:
>
> k := container[k] := value
>
> but that's not going to be more common. What I'm more likely to see is
> something like this:

Not about what's common, but about the full range of what's possible to express.

...

[Nick]
>>> Tuple unpacking:
>>>
>>>     What's the result type for "a, b, c := range(3)"? Is it a range()
>>> object? Or is it a 3-tuple? If it's a 3-tuple, is that 3-tuple "(1, 2,
>>> 3)" or "(a, b, range(3))"?

>> It's the range object range(3).  Same as in:
>>
>>     x = a, b, c = range(3)
>>
>> `x` is bound to the range object range(3).

> At the moment, "x = a, b, c := range(3)" will set c to range(3), then
> build a tuple of that with the existing values of a and b. You can,
> however, parenthesize the (a, b, c) part, and then it'll behave as you
> say.

Which would be really annoying to "repair".


>>> Whichever answers we chose would be surprising at least some of the
>>> time, so it seems simplest to disallow such ambiguous constructs, such
>>> that the only possible interpretation is as "(a, b, range(3))"

>> That's why Guido would be happiest with the rule at the top.  "The
>> answers" can already be surprising at times with current assignment
>> statements, but they are well defined.  It would be mondo bonkers to
>> make up entirely different subtle answers ;-)

> Wholeheartedly agreed.

I'd like Guido to chime in again, because I'm pretty sure he won't
accept what's currently on the table.  There are two plausible ways to
repair that:

1. Continue down the road of making assignment expressions "exactly
like" assignment statements in their full generality.

2. Back off and limit assignment expressions to what appears to be the
overwhelmingly most common case motivated by looking at real code (as
opposed to constructing examples to illustrate pitfalls &
obscurities):

    identifier ":=" expression


More information about the Python-Dev mailing list