On 30 March 2018 at 02:53, Paul Moore <p.f.mo...@gmail.com> wrote:
> On 29 March 2018 at 16:27, Nick Coghlan <ncogh...@gmail.com> wrote:
>> On 28 March 2018 at 04:47, Paul Moore <p.f.mo...@gmail.com> wrote:
>>> To me, that would be the ideal. I assume there are significant
>>> technical challenges, though, as otherwise I'd have thought that would
>>> have been the approach taken when Python 3 fixed the name leaking
>>> issue from Python 2.
>>
>> It isn't avoiding the names leaking that's particularly challenging
>> (there are several viable ways to do that), it's making sure that
>> inner scopes can still see them. For example:
>>
>>     lazy_and_eager = [((lambda: i), (lambda i=i: i)) for i in range(3)]
>>     for lazy, eager in lazy_and_eager:
>>         print(lazy(), eager())
>>
>>     # prints:
>>     2 0
>>     2 1
>>     2 2
>
> I'm really not sure what point you're trying to make here - are you
> saying that this is good or bad? Correct or incorrect? I don't really
> have any intuition about what's going on here, so I'd just have to
> work it out in terms of the defined scoping rules.

In this context, it's neither good nor bad, it just is :)

> And I'd then tell
> whoever wrote it to rewrite it more clearly ;-)

Aye, we get to do that in a code review, but the compiler doesn't - it
has to figure out how to make it do something at least reasonably
defensible.

> Maybe a real-life case where this was important would clarify what
> counts as intuitive here - but as it stands,I don't really care.

The fact that deep nesting of lexical scopes within an expression is
almost always going to be an unreadable mess in practice is one of the
reasons I don't think there's a strong case for either backwards
compatibility breaks *or* significant increases in the overall
semantic complexity.

Any sensible coding style is already going to say "Don't do that, it's
too hard to read", so we're mainly caring about it at all based on our
own senses of engineering aesthetics and a general dislike of
implementation details leaking through as user visible semantic
differences.

>> While it's *technically* feasible to hide "i" from the outer scope
>> without hiding it from inner scopes with a variable renaming based
>> approach, you end up having to design and document a separate lexical
>> scoping mechanism that's distinct from the one that functions already
>> use. I really didn't want to do that, so I proposed just using the
>> existing scoping mechanism instead, and while that has definitely had
>> its quirks, I'm still happy enough with it a decade later to call it a
>> successful approach.
>
> I do think the current implementation is a pretty good compromise. I'd
> be reasonably OK with not changing anything in this area. But this
> discussion was prompted by some of the debates around statement local
> variables, so "not changing anything" includes, in my mind, "not
> trying to make statement local variables work" as they interact badly
> with the current scoping behaviour in this area.

It's specifically lexical closures that lead to things getting weird,
and that's a key rationale for PEP 572's current recommendation that
statement locals be completely invisible to nested scopes. Trying to
have a subscope that isn't visible to the rest of the function it's
in, while still being visible to nested scopes defined within that
subscope, seems to lead to sufficient conflicts in reference lifecycle
and visibility that just using a real nested scope instead ends up
being preferable.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to