
On Wed, May 9, 2018 at 8:42 PM, Chris Angelico <rosuav@gmail.com> wrote:
On Thu, May 10, 2018 at 1:33 PM, Guido van Rossum <guido@python.org> wrote:
(I vaguely recall this has been brought up before, but I'm too lazy to find the subtread. So it goes.)
PEP 572 currently seems to specify that when used in expressions, the precedence of `:=` is lower (i.e. it binds more tightly) than all operators except for the comma. I derive this from the single example `stuff = [[y := f(x), x/y] for x in range(5)]`.
From this it would follow that `f(a := 1, a)` is equivalent to `a = 1; f(1, 1)`, and also that `(a := 1, a)` is equivalent to `a = 1; (1, 1)`. (Although M.A.L. objected to this.)
But what should `a := 1, 1` at the top level (as a statement) do? On the one hand, analogy with the above suggest that it is equivalent to `a = 1; (1, 1)`. But on the other hand, it would be really strange if the following two lines had different meanings:
a = 1, 1 # a = (1, 1) a := 1, 1 # a = 1; (1, 1)
I now think that the best way out is to rule `:=` in the top level expression of an expression statement completely (it would still be okay inside parentheses, where it would bind tighter than comma).
I would have := bind more tightly than the comma. Consider:
a = 1, x := 2, 3
IMO the only sane interpretation is "x = 2; a = 1, 2, 3". Effectively, the := operator does not like to play with commas; we've already ruled out "a, b := range(2)" as a means of unpacking, so it makes more sense to have that simply mean "b = range(2); a, b".
Oh, I hadn't even though of combining the two in one statement. That example is truly horrible (on first skim I didn't even notice it used two different assignment operators!) and strengthens my confidence that we should just disallow an un-parenthesized `:=` operator at the top level, where now the top level includes the RHS of a classic assignment. -- --Guido van Rossum (python.org/~guido)