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

Tim Peters tim.peters at gmail.com
Sat Apr 21 22:22:19 EDT 2018


[Christoph Groth <christoph at grothesque.org>]

> Still, it seems weird to have two different ways of binding names in > the language where one would be sufficient (i.e. the old one would > remain only for backwards compatibility). From the point of view of > someone who's new to the language that's two things to learn instead > of just one.

[Tim]

But they're very different in a key respect. the value of an assignment expression is the value assigned. Asking "what's the value of a statement?" doesn't even make sense in Python (whether an assignment statement or any other kind of statement).

[Christoph]

There are also no function call statements in Python. People are happily using function call expressions as statements when not interested in their value.

Sure.

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)

knowing that an assignment statement never displays any output on its own. If an assignment statement did return a result, almost all shells would display it. Shells typically don't care at all what you typed at them, they just care whether or not executing the compiled code returns None:

result = execute_code()
if result is not None:
    display(repr(result))

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?

The worst possible ;-) answer is "well, since

a=b

is fine as an assignment statement, it must mean that we bind the value of b to name a and then pass b's value to f() as its first positional argument". That reading would break countless lines of code using keyword arguments. If you're willing to concede that's too much breakage to bear, then you have to identify and spell out "the rules" for every case in which something that "looks like an assignment expression really isn't, depending on context".

But since I have no interest in pursuing this, I'll stop there :-)

Syntax-wise, if replacing = by := everywhere is unthinkable, as it seems, there's still the possibility (not completely ruled out by Guido ;-) to use = for assignment expressions but require extra parens for safety.

That would be received less well than the current PEP. The people it would hurt the most are newcomers from other languages who habitually put every "if" and "while" test in parentheses, because that's what they're used to doing (e.g., in C). Many of us still remember our initial relief when we realized we'd never piss away hours debugging an

assert(n=1)

or if (x=0.0)

typo/thinko again. Reintroducing that possibility would get an instant -1 from me, because I don't want to debug that same mistake for other people on Stackoverflow either - my time there is wholly consumed by explaining why .1 + .2 doesn't display exactly "0.3" ;-)

Thus, it seems to me that redefining assignments as expressions everywhere is a feasible, if radical, idea. Compared to a dedicated syntax for "binding expressions" it would be conceptually simpler, but would provide more possibilities to shoot oneself in the foot.

As above, it wouldn't remain so simple after hammering out the detailed rules for deciding when and where something that "looks like an assignment expression" really is one.

For an example of a fine language that makes no distinction between "statements" and "expressions" at all, Icon is top on my list. That can work out fine - but Icon was designed that way from the start. And, of course, like every sane language that has wholly general assignment expressions, Icon uses ";=" as the assignment operator, and "=" for numeric equality testing ;-)

[1] https://mail.python.org/pipermail/python-dev/2018-April/152780.html



More information about the Python-Dev mailing list