On Sat, Apr 19, 2014 at 10:38:39AM -0400, Nick Coghlan wrote:
> On 19 Apr 2014 00:27, "Steven D'Aprano" <st...@pearwood.info> wrote:
> >
> > On Fri, Apr 18, 2014 at 10:31:29PM -0400, Nick Coghlan wrote:
> > > After spending some time talking to the folks at the PyCon Twisted
> > > sprints, they persuaded me that adding back the iterkeys/values/items
> > > methods for mapping objects would be a nice way to eliminate a key
> > > porting hassle for them (and likely others), without significantly
> > > increasing the complexity of Python 3.
> >
> > It would also considerable add to the cruft of Python 3. One motive for
> > going through the pain of Python 2 to 3 migration was to remove cruft.
> > Adding it back in again is not just an aid to porting but actively
> > making Python 3 a worse (well, "less better") experience.
> 
> The cruft is unavoidable in this case. The decision we face is *where the
> cruft lives*, and *how much work is involved* in creating that cruft.

"How much work" is "very little". This problem is not of the same 
magnitude as trying to deal with unicode literals in a polyglot module, 
or the other string/bytes issues. A lot of the time, we don't even care 
whether iterating over dict.foo() gives a list, an iterator or a view. 
For the times we do care, it isn't hard to use a helper.

As for "where the cruft lives", that's the crux of the matter. In my 
opinion, the decision hinges on this question:

   Are iterkeys(), iteritems() and itervalues() the new, preferred 
   APIs for keys(), items() and values(), with the old APIs being 
   kept only for backward compatibility?

If so, then adding them to the language is certainly the right place. 
The old APIs could be deprecated, or even just left with a note in the 
docs that they aren't yet formerly deprecated but will be some day, in 
the meantime the new iterator-based APIs are preferred.

But if the keys(), items() and values() view-based APIs remain the 
preferred API, then I don't believe the backwards-compatibility layer 
belongs in the language. I believe it belongs as an external library, or 
even just a few helpers on an ad hoc basis.

If this is being driven by Twisted, I think that the onus needs to be on 
them to demonstrate how it will help them. Their official plans are to 
support Python 3.3, and they seem to have made a lot of progress towards 
it:

http://twistedmatrix.com/trac/wiki/Plan/Python3

so unless they drop 3.3 and 3.4 (do we want to encourage that?) 
this change won't even help them.


> Status quo: we preserve the "purity" of the Python 3 mapping API, and
> require every developer making the transition from Python 2 to Python 3
> replace every occurrence of these methods with a helper function that is
> not idiomatic code in either language.

That is part of the cost of writing polyglot code. It's messy. But 
that's not new, and it's not unique to 2+3 polyglot code, it happens 
every time a new feature is added or removed in a point release.


> My proposal: we add three trivial helper methods to the Python 3 mapping
> API. For the cost of 3 additional methods that are easily explained in
> terms of combining a builtin with other existing methods, a whole pile of
> work just evaporates for affected segments of the community.

And a whole lot of additional work suddenly appears for *different* 
affected segments of the community, e.g. educators, writers.

This is where the standard objections to any new language feature come 
out. Just because this feature is being added for the benefit of 
transitional 2+3 polyglot code doesn't render these objections 
irrelevant. I trust I don't need to go through the usual list.

By the way, I earlier suggested adding iter* and immediately deprecating 
them, but I don't believe you commented on that. Even if they are never 
removed, the deprecation warning would be a very strong signal that they 
really are only added as an aid to writing 2+3 code, and are not 
intended as long-term language features. Writers can then ignore the 
iter* API, or at least relegate it to an appendix, and educators might 
not be quite able to ignore it but they can at least say "don't use 
them" in good conscience. The dict iteration issue for polygot code now 
becomes easy: just silence the warning, and you're good to go for at 
least three more years, and likely longer.

I think immediate deprecation would be a reasonable compromise position, 
and would like to hear your thoughts on that.


> > So while I'm sympathetic to wanting to ease the 2/3 transition, even at
> > the expense of re-introducing some cruft when unavoidable, I don't think
> > that the difficulty of dealing with dict items|iteritems|viewitems etc.
> > justifies re-adding cruft.
> 
> The cruft will be there regardless, the only question is whether it exists
> in the definition of Python 3 or is distributed across all of the single
> source projects supporting both 2 & 3.

The same reasoning applies to every change between 2 and 3. If 
dict.iter* methods get language support, why not all the others?

If somebody is feeling particularly brave, and wants to argue that 
dropping (almost all) 2.x features was a mistake and they should be 
readded in bulk, I would much rather have that debate now rather than 
spending the next eighteen months arguing about it feature by feature.


[...]
> I spend a fair bit of time talking to users that have put a lot of work
> into supporting a language transition that doesn't really help them
> personally. A non-trivial number of them are deeply, viscerally angry about
> what they see as pointlessly changing the spelling of a core language
> feature for no real technical gain.
> 
> So let me be clear: this is *not* a proposal driven primarily by technical
> considerations. Rather, it is a social one, where we do something simple
> and easy and low cost for us to send a clear message to a set of users that
> feel justifiably angry about the amount of work we imposed on other members
> of the community by putting Python 2 into maintenance mode that we do value
> their time and energy, and are willing to show some flexibility in adding
> "not harmful" changes to Python 3 that don't significantly increase the
> complexity of the language, while making it easier to write single source
> code that looks like idiomatic Python code.

Thank you for raising this explicitly, I think it is important to 
acknowledge people's feelings. But it's also important to acknowledge 
that just because people are angry, doesn't mean we have to do more than 
acknowledge that they are angry. Being angry doesn't give one better 
insight to the issue, or make one's preferred solution the right 
solution. (If anything, the opposite: angry people's solutions to 
problems tend to make things worse rather than better.)

I think it is also important to acknowledge that while some people may 
feel angry about Python 3 changes, some people are *extremely happy* 
that Python 3 has cleaned up some language cruft, and will be equally 
justifiably, viscerally angry if it is put back. If this is a permanent 
language feature, the *entire* Python community will be dealing with 
this long after Twisted has dropped support for Python 3.5, and maybe 
long after Twisted has been abandoned and is just a memory.

Let me be frank, and call a spade a bloody shovel as we say in 
Australia: from the evidence presented so far (very little), I don't 
think that the Twisted folks are justified in their anger about 
dict.iter* methods or the difficulty in handling them in polygot code. 
It seems to me that they are being awfully precious about a few trivial 
helpers. (I do not speak of other 2+3 issues, which I know can be more 
significant.) I think they are using their privileged position as a 
major Python library to try to impose an unnecessary and harmful (albeit 
minor) regression on Python 3 with no technical justification, for 
"social" (i.e. personal) reasons which I won't speculate about.

If it had been some minor third party library requesting this change, 
the answer would be obvious:

    Not every two or three line function needs to be a built-in.


I do not accept that using helper functions is unpythonic. On the 
evidence presented so far, I don't believe that there is any technical 
justification for adding iter* methods back to the dict API, and if we 
care about social issues, how about the social issues that doing this 
can and will be seen by some as a de facto acknowledgement that Python 3 
was a mistake?

It's one thing to add big, complicated features which are hard for 
individual projects to deal with as an aid to porting, e.g. the whole 
bytes/str issue, but when something as simple as the proposed iter* 
methods is treated as if it were a major imposition on third-parties 
that needs to be fixed in the core language, that's a big signal that 
the whole Python 3 exercise was a mistake. I do not believe it is a 
mistake, and I don't want to send a signal that it was.

I think Terry Reedy's comment earlier is significant:

    [quote]
    When I suggested that PEP 414 might be seen as a precedent for 
    restoring more of Py2, I was trashed for saying so. "No, no, u'' is 
    a unique case. [it is] This will be the last proposal like this." 
    What will come next?
    [end quote]

What's the next Python 2 feature that will be re-added after this one? A 
lot of people are angry that the cmp argument to sorted() and 
list.sort() was removed, and just don't like functools.cmp_to_key, never 
mind that it actually solves their technical problem. Should that be 
added back, "to aid in porting (but really just so people will feel good 
about the fact that we're listening to them)"?

With no good technical justification for this regression, I fear that 
this sets a precedence that will not end until we have:

    from __future__ import just_give_me_back_my_python2_dammit

in another release or three.

I don't believe that will happen, the line *will* be drawn somewhere, 
before Python 3 dies a death of a thousand cuts. I think that the right 
place to draw the line is *here*, not the next time, or the time after 
that. I think that the decision should be made on technical reasons, not 
so people feel that they are being listened to.

(That will only end with resentment, "Why do you listen to *them* and 
not *me*? Am I not important enough?".)

2+3 compatibility code should only live in the language rather than in 
the polygot code when there are compelling technical reasons for it to 
do so, not just to avoid a couple of two or three line helpers.



-- 
Steven
_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to