[Python-Dev] Informal educator feedback on PEP 572 (was Re: 2018 Python Language Summit coverage, last part)

Nick Coghlan ncoghlan at gmail.com
Sun Jun 24 03:10:28 EDT 2018

On 24 June 2018 at 16:53, Chris Angelico <rosuav at gmail.com> wrote:
> On Sun, Jun 24, 2018 at 4:33 PM, Nick Coghlan <ncoghlan at gmail.com> wrote:
>> On 24 June 2018 at 15:56, Steven D'Aprano <steve at pearwood.info> wrote:
>>> On Sun, Jun 24, 2018 at 02:33:59PM +1000, Nick Coghlan wrote:
>>>> Given that PEP 572 *is* proposing implicit comprehension state export,
>>> "Implicit" and "explicit" are two terms which often get misused to mean
>>> "I don't like it" and "I do like it".
>>> Making the intentional choice to use an assignment expression is not
>>> really "implicit" in any meaningful sense.
>> No, it's actually implicit: there's an extra "global NAME" or
>> "nonlocal NAME" in the equivalent code for a comprehension that isn't
>> there in the as-written source code, and doesn't get emitted for a
>> regular assignment expression or for the iteration variable in a
>> comprehension - it only shows up due to the defined interaction
>> between comprehensions and assignment expressions.
> The implicit "nonlocal NAME" is only because there is an equally
> implicit function boundary. Why is there a function boundary marked by
> square brackets? It's not saying "def" or "lambda", which obviously
> create functions. It's a 'for' loop wrapped inside a list display.
> What part of that says "hey, I'm a nested function"?

Nothing - that's why I refer to them as implicitly nested scopes (vs
the explicitly nested scopes in functions and lambda expressions,
where the scope is introduced via keyword).

However, there's still a major behavioural tell at runtime that
they're running in a nested scope: the iteration variables don't leak.
(There are other tells as well, but not ones that most folks are
likely to encounter)

> So if there's an implicit function, with implicit declaration of a
> magical parameter called ".0", why can't it have an equally implicit
> declaration that "spam" is a nonlocal name?

Because comprehensions don't do that for their iteration variables,
because assignment expressions don't do that when used in explicitly
nested scopes, because the required implicit scope declarations are
context dependent, and because even such gyrations still can't hide
the existence of the comprehension's implicitly nested scope when
dealing with classes and the two-argument form of exec().

Since the implicitly nested scopes can't be hidden, it makes far more
sense to me to just admit that they're there, and provide explicit
syntax for cases where folks decide they really do want name bindings
to leak out of that scope (whether those name bindings are assignment
expression targets or the iteration variables themselves).


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-Dev mailing list