[Python-Dev] PEP 572: Assignment Expressions

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(iterator_returning_a_billion_strings)
>
> 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