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

Tim Peters tim.peters at gmail.com
Mon May 14 12:47:58 EDT 2018


>>     total = 0
>>     progressive_sums = [total := total + value for value in data]

[Greg Ewing <greg.ewing at canterbury.ac.nz>]
> I'm skeptical that it's a good idea to encourage this kind of thing
> in the first place.

Adding a feature is creating possibility for its use, not encouraging
its use.  I'd hate to, ,e.g., see people encouraging use of ternary-if
either,  _Sometimes_ ternary-if is exactly right, both shortening code
and increasing clarity.  But not often.  Ditto for metaclasses, the
ability to nest blocks 20 levels deep, on & on.  That they can be
abused, and sometimes are abused, is a very weak argument against
them.  On a scale of 1 to 1000000?  Maybe 23 ;-)

The specific use case that grabbed Guido's attention on this one
wasn't the above, but:

    while any(n % p == 0 for p in small_primes):
        // divide p out of n - but which p succeeded?

 _General_ features turn out to have multiple good uses, not all of
which are anticipated.  I think this is an example of that.  It's easy
to miss that the argument to `any()`  runs in an entirely different
scope, so that its local `p` vanishes when `any()` completes.

It's not proposed to change that either, because people overwhelmingly
seem to want `for` targets not to leak.  Fine by me.

Under the proposal, it's straightforward to use an assignment
expression to "export" p's last materialized value:

    while any(n % (factor := p) == 0 for p in small_primes):
        n //= factor

To my eyes, the most surprising thing about that is why it's necessary
to "export" p's winning value to begin with.  "Because for-targets
always vanish, so there's another form of explicit binding that
doesn't" is a reasonably satisfying explanation.

Nick would be happiest, and I'd be "happy enough", if all forms of
binding remained "local" and instead we fiddled the syntax to allow
explicitly declaring the desired scope.  Then, e.g.,

    while any(<nonlocal p>
                    n % p == 0 for p in small_primes):
        n //= p

wouldn't need an assignment expression at all.  But Guido doesn't like
that.  I think he wants to hide, so far as humanly possible, that
listcomps and genexps happen to implemented now by synthesizing
functions.


More information about the Python-ideas mailing list