[Python-ideas] Inline assignments using "given" clauses

Tim Peters tim.peters at gmail.com
Mon May 14 03:43:56 EDT 2018

[Greg Ewing <greg.ewing at canterbury.ac.nz>']
> Can someone explain to me why it was considered a bad
> thing that for-clauses leaked names in comprehensions,

Because you can't write a list comprehension or generator expression
AT ALL without specifying a `for` loop header, so whether its
target(s) leaks is an issue in virtually every listcomp/genexp ever
written, and that people tend to use short (typically 1-letter) names
for for-targets, so unintentional stomping on names is exceptionally
likely in this context.

> but it will be a good thing for inline assignments to leak names
> from them?

Because you never _need_ to use an assignment expression to write a
listcomp/genexp.  You have to go out of your way to use it.  Which
will probably be rare in listcomps;genexps,, not virtually 100% of the
time as with for-targets.  Then you get what you went out of your way
to explicitly ask for:  a name for some subexpression result.

Otherwise it's essentially impossible to explain why:

    total = 0
    sums = [total := total + value for value in data]
    assert sums[-1] == total

"blows up", despite that its intent is obvious, unless you first
explain to a user how the listcomp is implemented via an invisible
synthetic function created by magic, inside of which `total`  has
nothing to do with the `total` they see on the first line.
UnboundLocalError - WTF?

That's why leaking "is good".  It works both directions:  the outer
name leaks _into_ the body too, not just _out_ of it.  Things that
"look like" they should obviously work do work then, and a user can
remain blissfully unaware of the implementation.. Of course you can
also find cases in which it's not wanted.

If it doesn't leak the kind of use shown above can't be done at all
via listcomps (at least not straightforwardly).

If it does leak, the subset of cases where leaking is unwanted _of_
the subset of cases in which a listcomp//genexp uses an assignment
expression at all are indeed inconvenienced.

So - surprise!  It's a tradeoff, something we've never faced before ;-)

More information about the Python-ideas mailing list