On 26 February 2018 at 01:08, Chris Angelico <rosuav@gmail.com> wrote:
Speaking as a C programmer who's quite happy to write code like "while
((var = func()) != sentinel)", I wouldn't object to this coming up in
Python; the "as name" syntax has the huge advantage over C's syntax in
that you can't accidentally leave off one equals sign and get the
wrong behaviour. But I know that a lot of people dislike this at a
more fundamental level.

If someone wants to push for this, I think it probably needs a PEP -
it's a point that comes up periodically. I don't think it's ever had a
PEP written about it, but it's a bit hard to search for; maybe someone
else knows off hand?

PEP 3150 is the most closely related PEP we have at the moment (and that only works for simple statements, since it relies on using a trailing block to name the subexpressions).

The "(EXPR as NAME)" syntax comes up periodically, especially in the context of while loops (where it would allow a direct translation of C-style embedded assignment idioms).

In addition to the potential confusion for "with (EXPR as NAME):" vs "with EXPR as NAME:" (and the similar ambiguity for "except" clauses), some other major questions to be resolved are:

* are statement locals in a class namespace turned into attributes on the resulting class? (it would be more useful if they weren't)
* are statement locals in a module namespace turned into attributes on the resulting module? (it would be more useful if they weren't)
* are statement locals in a function/generator/coroutine namespace kept alive until the entire call terminates? (it would be more useful if they weren't)
* do currently defined statement locals appear in calls to locals() or in frame.f_locals?
* can lexically nested scopes see names bound this way? (a lot of complex name resolution problems disappear if they can't, plus you get a clearer distinction between these and regular function locals)

To be interesting enough to potentially be worthy of syntax, I think name bindings written this way would need to be truly statement local:

* reference is released at the end of the statement (whether simple or compound)
* no ability to close over them (this goes hand in hand with eagerly dropping the reference)
* we play name mangling games and/or use different opcodes to avoid overwriting regular function locals and to avoid appearing in locals()

That's still only enough to get the concept into python-ideas territory though (as per the discussion of "(EXPR as .NAME)" in https://mail.python.org/pipermail/python-ideas/2018-February/049002.html) - it's still a *long* way from being fully baked enough to make into a concrete change proposal for 3.8+.

Cheers,
Nick.

--
Nick Coghlan   |   ncoghlan@gmail.com   |   Brisbane, Australia