[Python-Dev] Looking for examples: proof that a list comp is a function

Nick Coghlan ncoghlan at gmail.com
Mon May 14 08:16:29 EDT 2018


On 14 May 2018 at 04:05, Tim Peters <tim.peters at gmail.com> wrote:

> I say "pretty much" because, for whatever reason(s), it seems to be
> trying hard _not_ to use the word "function".  But I can't guess what
> "then passed as an argument to the implicitly nested scope" could
> possibly mean otherwise (it doesn't make literal sense to "pass an
> argument" to "a scope").
>

I think my motivation was to avoid promising *exact* equivalence with a
regular nested function, since the define-and-call may allow us
opportunities for optimization that don't exist when those two are
separated (e.g. Guido's point in another thread that we actually avoid
calling "iter" twice even though the nominal expansion implies that we
should). However, you're right that just calling it a function may be
clearer than relying on the ill-defined phrase "implicitly nested scope".

For Chris's actual question, this is part of why I think adding
"parentlocal" would actually make the scoping proposal easier to explain,
as it means the name binding semantics aren't a uniquely magical property
of binding expressions (however spelled), they're just a new form of target
scope declaration that the compiler understands, and the binding expression
form implies. Note: eas*ier*, not easy ;)

It also occurs to me that we could do something pretty neat for class
scopes: have parent local declarations in methods target the implicit
lexical scope where __class__ lives (to support zero-arg super), *not* the
class body. That would entail adding a "classlocal" declaration to target
that implied scope, though.

That would give the following definition for "lexical scopes that parent
local scoping can target":

- module globals (parentlocal -> global)
- function locals, including lambda expression locals (parentlocal ->
nonlocal)
- implicit class closure, where __class__ lives (parentlocal -> nonlocal in
current scope, classlocal in class scope)

Most notably, in the synthetic functions created for generator expressions
and comprehensions, a parentlocal declaration in a child scope would imply
a parentlocal declaration in the synthetic function as well, propagating
back up the chain of nested lexical scopes until it terminated in one of
the above three permitted targets.

Using the explicit forms would then look like:

    from __future import parent_scopes # Enable the explicit declaration
forms

    class C:
        classlocal _n # Declares _n as a cell akin to __class__ rather than
a class attribute
        _n = []
        @staticmethod
        def get_count():
            return len(_n)

    assert not hasattr(C, "_n")
    assert C.get_count() == 0

    def  _writes_to_parent_scope():
        parentlocal outer_name
        outer_name = 42

   assert outer_name == 42

I'm still doubtful the complexity of actually doing that is warranted, but
I'm now satisfied the semantics can be well specified in a way that allows
us to retain the explanation of generator expressions and comprehensions in
terms of their statement level counterparts (with the added bonus of making
"__class__" a little less of a magically unique snowflake along the way).

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20180514/42643efd/attachment.html>


More information about the Python-Dev mailing list