[Python-Dev] PEP 572: Assignment Expressions (original) (raw)

Christoph Groth christoph at grothesque.org
Sun Apr 22 05:29:06 EDT 2018


Tim Peters wrote:

[Christoph Groth <christoph at grothesque.org>] > I hope to have shown [1] that the same could be done for > assignments. A consistent value can be defined for any assignment > statement. So, all assignment statements could be redefined as > expressions and the language would continue to work and even be > (perfectly?) backwards-compatible.

Except for shells. When I type, e.g., >>> xs = sorted(iteratorreturningabillionstrings) I really don't want to wait for hours before I can type again ;-) In the same way now, when someone calls a function at a shell but doesn't want to see its result, they do something like >>> xxx = function(a, b, c)

Yes, that's a serious problem with making all assignments expressions. Assignments are so common in interactive use that displaying their values could be quickly annoying.

There are several possible solutions. For example, the IPython shell interprets a trailing semicolon as "do not show the result of the expression".

A better solution seems to be to only treat assignments that are surrounded by the mandatory parens as expressions and keep the old-style assignments as statements, e.g.

a = 3 (a = 3) # currently a SyntaxError 3

So, strictly speaking, there would be distinct assignment statements and expressions, but it would be still easy conceptually because one could say:

Any valid assignment statement can be turned into an expression by surrounding it with parentheses. There is no difference in semantics.

There's also that you're not considering the other half: that every existing assignment statement could be viewed as being as expression does not imply that every existing assignment statement could be used everywhere an expression can be used. Syntax matters, and function call argument lists in particular already bristle with their own meanings for commas, equal signs, and asterisks. The language was designed with "and the twain shall never meet" in mind ;-) For example, what would

f(a=b) mean?

It would, of course, mean the same as it does now. (Otherwise backwards compatibility would be broken.) However,

f((a=b))

which currently is a syntax error, would mean: bind the value of 'b' to the name 'a' and call 'f' with the value of that expression. The extra parens would be required around any assignment expression. I believe that this also solves all the other problems that you raise with regard to commas etc.

So, you see, promoting assignments to expressions is indeed feasible. The advantages are the conceptual simplicity, and the familiar syntax.

The syntax is also a disadvantage, because it is somewhat ugly:

while (item = get()): process(item)

There's also potential for misuse, but firstly that is something that is not unheard of in Python and secondly assignment expressions could be (at least initially) limited to only a subset of the forms that are allowed for assignment statements.

If I had to choose between the above and ":= binding expressions", I guess I would tend to prefer the latter because they are sufficient, nicer looking and offer less potential for trouble. But I think that it is worth to fully discuss the above idea as well. IMHO it should be at least briefly mentioned in the "rejected ideas" of PEP 572, because it is arguably the most self-evident way to introduce name-binding expressions into the language.



More information about the Python-Dev mailing list