On 27.06.2018 5:36, Guido van Rossum wrote: > [This is my one response today] > > On Mon, Jun 25, 2018 at 12:40 PM Terry Reedy <tjreedy at udel.edu > <mailto:tjreedy at udel.edu>> wrote: > > On 6/24/2018 7:25 PM, Guido van Rossum wrote: > > I'd wager that the people who might be most horrified about it > > the (b) scoping rule change > > > would be people who feel strongly that the change to the > > comprehension scope rules in Python 3 is a big improvement, > > I might not be one of those 'most horrified' by (b), but I > increasingly > don't like it, and I was at best -0 on the comprehension scope > change. > To me, iteration variable assignment in the current scope is a > non-problem. So to me the change was mostly useless churn. Little > benefit, little harm. And not worth fighting when others saw a > benefit. > > > Fair enough, and by itself this might not have been enough reason to > make the change. But see below. > > However, having made the change to nested scopes, I think we should > stick with them. Or repeal them. (I believe there is another way to > isolate iteration names -- see below). To me, (b) amounts to half > repealing the nested scope change, making comprehensions half-fowl, > half-fish chimeras. > > > That depends on how you see it -- to me (b) just means that there's an > implicit nonlocal[1] to make the assignment have the (desirable) > side-effect. > > The key thing to consider here is whether that side-effect is in fact > desirable. For me, the side-effect of the comprehension's loop control > variable was never desirable -- it was just an implementation detail > leaking out. (And that's different from leaking a regular for-loop's > control variable -- since we have 'break' (and 'else') there are some > legitimate use cases. But comprehensions try to be expressions, and > here the side effect is at best useless and at worst a nasty surprise.) > > > and who are familiar with the difference in implementation > > of comprehensions (though not generator expressions) in Python 2 > vs. 3. > > That I pretty much am, I think. In Python 2, comprehensions (the > fish) > were, at least in effect, expanded in-line to a normal for loop. > Generator expressions (the fowls) were different. They were, and > still > are, expanded into a temporary generator function whose return > value is > dropped back into the original namespace. Python 3 turned > comprehensions (with 2 news varieties thereof) into fowls also, > temporary functions whose return value is dropped back in the > original > namespace. The result is that a list comprehension is equivalent to > list(generator_ expression), even though, for efficiency, it is not > implemented that way. (To me, this unification is more a benefit > than > name hiding.) > > > Right, and this consistency convinced me that the change was worth it. > I just really like to be able to say "[... for ...]" is equivalent to > "list(... for ...)", and similar for set and dict. "A shorthand to list()/dict()/set()" is actually how I thought of comprehensions when I studied them. And I was actually using list() in my code for some time before I learned of their existence. > (b) proposes to add extra hidden code in and around the temporary > function to partly undo the isolation. > > > But it just adds a nonlocal declaration. There's always some hidden > code ('def' and 'return' at the very least). > > list comprehensions would no > longer be equivalent to list(generator_expression), unless > generator_expressions got the same treatment, in which case they > would > no longer be equivalent to calling the obvious generator function. > Breaking either equivalence might break someone's code. > > > Ah, there's the rub! I should probably apologize for not clarifying my > terminology more. In the context of PEP 572, when I say > "comprehensions" I include generators! PEP 572 states this explicitly > (https://github.com/python/peps/blame/master/pep-0572.rst#L201-L202). > > Certainly PEP 572 intends to add that implicit nonlocal to both > comprehensions and generator expressions. (I just got really tired of > writing that phrase over and over, and at some point I forgot that > this is only a parenthetical remark added in the PEP's latest > revision, and not conventional terminology -- alas. :-) > > Part (b) of PEP 572 does several things of things to *retain* consistency: > > - The target of := lives in the same scope regardless of whether it > occurs in a comprehension, a generator expression, or just in some > other expression. > > - When it occurs in a comprehension or generator expression, the scope > is the same regardless of whether it occurs in the "outermost > iterable" or not. > > If we didn't have (b) the target would live in the > comprehension/genexpr scope if it occurred in a comprehension/genexp > but outside its "outermost iterable", and in the surrounding scope > otherwise. > > --- > > How loop variables might be isolated without a nested scope: After a > comprehension is parsed, so that names become strings, rename the > loop > variables to something otherwise illegal. For instance, i could > become > '<i>', just as lambda becomes '<lambda>' as the name of the resulting > function. Expand the comprehension as in Python 2, except for > deleting > the loop names along with the temporary result name. > > Assignment expressions within a comprehension would become assignment > expressions within the for loop expansion and would automatically > add or > replace values in the namespace containing the comprehension. In > other > words, I am suggesting that if we want name expressions in > comprehensions to act as they would in Python 2, then we should > consider > reverting to an altered version of the Python 2 expansion. > > > Possibly this is based on a misunderstanding of my use of > "comprehensions". Also, since your trick can only be used for > list/set/dict comprehensions, but not for generator expressions (at > least I assume you don't want it there) it would actually *reduce* > consistency between list/set/dict comprehensions and generator > expressions. > > --- > > In any case, I think (b) should be a separate PEP linked to a PEP for > (a). The decision for (a) could be reject (making (b) moot), accept > with (b), or accept unconditionally (but still consider (b)). > > > For me personally, (b) makes the PEP more consistent, so I'm not in > favor of breaking up the PEP. But we can certainly break up the > discussion -- that's why I started using the labels (a) and (b). > ---------- > [1] Sometimes it's an implicit global instead of an implicit nonlocal > -- when there's already a global for the same variable in the target > scope. > > -- > --Guido van Rossum (python.org/~guido <http://python.org/%7Eguido>) > > > _______________________________________________ > Python-Dev mailing list > Python-Dev at python.org > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/vano%40mail.mipt.ru -- Regards, Ivan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20180627/7c11a308/attachment-0001.html>
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4