|
|
Subscribe / Log in / New account

Things that won't change in Python

By Jake Edge
February 8, 2017

A lengthy and strongly opinionated post about Python features to the python-ideas mailing list garnered various responses there, from some agreement to strong disagreement to calling it "trolling", but it may also lead the Python community to better define what Python is. Trolling seems a somewhat unfair characterization, but Simon Lovell's "Python Reviewed" post did call out some of the fundamental attributes of the language and made some value judgments that were seen as either coming from ignorance of the language or simply as opinions that were stated as facts in a brusque way. The thread eventually led to the creation of a document meant to help head off this kind of thread in the future.

Good, bad, and ugly

Lovell's message started off with a short list of "The Good", but quickly moved into a list of "The Bad" that included more explanation of the features he disliked. It included entries for things he was unhappy with: the colons at the end of if, for, and similar statements (which he deemed unnecessary), the lack of an end statement for blocks (less readable), and no do-while loop. He also thought that the else clause for loops should have a different name (and suggested whenFalse), that print() should not have been changed to a function in Python 3 ("adds no positive value that I can see"), etc. As might be guessed, he ended with an entry for "The Ugly". It complained about non-zero integer values being treated as "true" ("crapulence from C" that violates the "explicit is better than implicit" principle from PEP 20).

Some of the entries in the good and bad lists were either incorrect or misunderstandings of how to use Python, which put Lovell on the wrong foot with many python-ideas readers. But his tone also put some off. As Stephen D'Aprano put it: "As a newcomer to this community, and apparently the language as well, do you understand how obnoxious and arrogant it comes across for you to declare what is and isn't 'good' and 'bad' about the language [...]". He warned Lovell that the tone of his message might make responses "blunt or even brusque", but he did reply at some length.

For example, D'Aprano pointed him at the FAQ entry that explains the reasons behind the colons for if, et al. (readability, essentially). He also disagreed strongly with the need for an end statement, but agreed that else for loops was misnamed (though it is too late to change that now). Meanwhile, D'Aprano said that he preferred treating non-zero numbers as true values.

Chris Angelico also thought that the way Python does truth testing is both helpful and non-ugly:

In Python, *everything* is either true or false. Anything that represents "something" is true, and anything that represents "nothing" is false. An empty list is false, but a list with items in it is true.

D'Aprano and Angelico both agreed with the decision to change print() to a function. Angelico said that it "adds heaps of positive value to a lot of people", while D'Aprano was more specific about the advantages:

Consistency: print doesn't need to be a special cased statement. It does nothing special that a function can't do. So why make it a statement?

As a function, it can be passed around as a first class value, used as a callback, monkey-patched or shadowed or mocked as needed. None of these things are possible with a statement.

Overall, the thread proceeded like most in Python mailing lists. Folks were generally helpful even when they were resolute about disagreeing with Lovell. On the other hand, Lovell didn't seem to quite pick up the vibe of the list. For example, responses like "I don't really see how that can be argued" or "I may be arrogant but I can't take it seriously" did not go over all that well.

Trolling?

Eventually, Guido van Rossum started a new thread entitled "How to respond to trolling". In it, he suggested that responding to Lovell's posts was counterproductive: "I think a much more effective response would have been a resounding silence." But several thought that was not entirely fair. Ned Batchelder said:

I don't like to use the term "trolling" except for people who are trying to annoy people. I think the recent thread was misguided, but not malicious. I do agree that the thread should have ended at "unless you are seriously proposing a change to the language, this is not the right list."

There were a number of suggestions in the original thread for Lovell to take the topic to a different mailing list (python-list, which is for more general Python discussions). Since Lovell wasn't really suggesting changes to the language (at least formally), some thought the discussion belonged on a different list. Though Nick Timkovich wasn't sure that even if Lovell had proposed the changes it would be a topic for python-ideas: "If you're proposing throwing half of Python's current syntax in the bin, this isn't the right list either."

However Van Rossum was adamant that the Lovell's post did not deserve a response:

Whether the intent was to annoy or just to provoke, the effect was dozens of messages with people falling over each other trying to engage the OP, who clearly was ignorant of most language design issues and uninterested in learning, and threw some insults in for good measure. The respondents should have known better.

But D'Aprano saw things differently. What Van Rossum had suggested was effectively "shunning" Lovell, which is "a particularly nasty form of passive-aggression, as the person being shunned doesn't even get any hint as to what they have done to bring it on". He also pointed out that it may not have been clear to Lovell that he was crossing a line, because it is an unwritten one:

Giving a newcomer the Silent Treatment because they've questioned some undocumented set of features not open to change is not Open, Considerate or Respectful (the CoC). Even if their ideas are ignorant or ill-thought out, we must give them the benefit of the doubt and assume they are making their comments in good faith rather than trolling.

Things that won't change

In an attempt to rectify the "undocumented" piece, D'Aprano proposed an informational PEP called "Things that won't change in Python". In it, he listed a number of things that are known to be immutable in Python, but that perhaps those outside the community are not aware of. The rationale, as described in the PEP, is to reduce noise on python-ideas and other lists by heading off suggestions that have no chance to be accepted "because the benefit is too little, the cost of changing the language (including backwards compatibility) is too high, or simply because it goes against the design preferred by the BDFL".

Some of the things listed in the PEP are fairly obvious (Python 3 will not be abandoned, there will be no Python 2.8), some were at least partly in response to Lovell's post (colons after if and the like, no end statement, print() will remain a function), and others came from recurring suggestions to the lists (no braces around blocks, significant indentation will remain, the >>> interactive prompt will stay as the default). Each entry comes with a bit of justification, often with links to a FAQ entry or other documentation.

In general the response was positive. There was naturally some wordsmithing (or bikeshedding) over the name and whether it should be a PEP or something else, but there was little disagreement over the listed choices—unsurprisingly. Van Rossum said that he had not followed the discussion closely, but that it made sense to delineate some unchangeable features of the language:

People who come in with enthusiastic proposals to fix some pet peeve usually don't have the experience needed to appreciate the difficulty in maintaining backwards compatibility. (A really weird disconnect from reality happens when this is mentioned in the same breath as "please fix the Python 2 vs. 3 problem". :-)

I would also guess that for things that are actually controversial (meaning some people hate a feature that other people love), it's much easier to explain why it's too late to change than it is to provide an objective argument for why the status quo is better. Often the status quo is not better per se, it's just better because it's the status quo.

Lovell did reply to Van Rossum's "trolling" message, but was still on the offensive ("More than half of what I suggested could have and should be implemented."). He also continued to insist that Python's "truthiness" is ugly: "Calling truthiness of non boolean data 'Ugly' is an insult? It is ugly." Brett Cannon, who is one of the list administrators, tried one more time to explain why Lovell was not getting the response he was seemingly looking for:

It's this sort of attitude which puts people off. It is your opinion that it should be implemented, not a matter of fact as you have stated it. Just because something could be done doesn't mean it should be done. You're allowed to have your opinion, but stating it as anything but your opinion does not engender anyone to your opinion.

That led to a bit of a digression on the term "warts", which is sometimes used in the Python community to describe some missteps and misfeatures that exist in the language. It was mostly agreed that warts are "ugly" at some level, but it is a self-applied term, which makes it a bit more acceptable. And Van Rossum is not even sure they are missteps, exactly:

I believe that most of the warts are not even design missteps -- they are emergent misfeatures, meaning nobody could have predicted how things would work out.

In the end, the situation was handled pretty well, as is always the case in the Python community, it seems. One can imagine a much ruder response that a critical post like that might receive in other free-software communities. So far, it doesn't seem like the PEP has gone anywhere since it was discussed in mid-January, but the exercise and discussion were useful; if nothing else it can serve as a place to point the next person who comes along with "great ideas" that will never become a part of Python.



to post comments

Things that won't change in Python

Posted Feb 9, 2017 9:59 UTC (Thu) by mjthayer (guest, #39183) [Link]

> Eventually, Guido van Rossum started a new thread entitled "How to respond to trolling". In it, he suggested that responding to Lovell's posts was counterproductive: "I think a much more effective response would have been a resounding silence." But several thought that was not entirely fair.

"Don't feed the [person writing strongly opinionated things]" is a nice idea, but it doesn't seem to be very effective. To work it requires unspoken co-operation between everyone who might be reading a message who is able to post a reply. Wouldn't a better response, where private answers are available, be "only reply by private message unless you have a good reason not to"? Private answers are less likely to keep an unwanted thread alive and more likely to tie up the person writing in an opinionated way, keeping them from posting publicly. And people who do respond publicly inappropriately, or to repeat things which have already been said publicly, can also be asked privately not to do so.

Things that won't change in Python

Posted Feb 9, 2017 10:18 UTC (Thu) by kokada (guest, #92849) [Link]

Just a question, is Lovell a Ruby guy? His proposals seems very similar to decisions made in Ruby language.

Huh?

Posted Feb 9, 2017 15:57 UTC (Thu) by ncm (guest, #165) [Link] (4 responses)

This is a very strange topic for a lead article on LWN, and a very strange treatment of the topic. I found it uniquely unenlightening for an LWN article. Nothing suggested why I should care about any of the points or any of the opinions quoted. The title seems irrelevant to the text.

I am hoping our Benevolent Editor can offer a hint about why it matters. Is it that Python as a community has lost its ability to discuss topics rationally?

Huh?

Posted Feb 9, 2017 16:41 UTC (Thu) by corbet (editor, #1) [Link]

Many projects are subject to a stream of people who show up with "good ideas" that can never be adopted for any of a number of reasons. This topic was a look at how one project deals with this problem and an attempt to document why some recurring ideas will never fly. I thought the topic was interesting, sorry if you disagree. We'll return to RPM-v.-Debian flamewars soon, don't worry :)

Huh?

Posted Feb 9, 2017 21:50 UTC (Thu) by craniumslows (guest, #114021) [Link]

I feel that the author was trying to be as neutral on the topic while reporting on what had transpired. The proposed PEP (https://lwn.net/Articles/713969/) and link to PEP 20 were also useful context. The title I would guess comes from the proposed PEP. I enjoyed it.

Huh?

Posted Feb 9, 2017 23:06 UTC (Thu) by neilbrown (subscriber, #359) [Link]

> This is a very strange topic for a lead article on LWN, ...

I think it would have fit perfectly in the "Maintainership" section I tried to propose recently. Promoting it from that (nonexistent) place to the front page is just an editorial decision based on available space and content

> I found it uniquely unenlightening for an LWN article.

I thought it was a great good-news story. A good counter-balance to the occasional "yet another flame war" stories.

Huh?

Posted Feb 16, 2017 9:04 UTC (Thu) by oldtomas (guest, #72579) [Link]

> I found it uniquely unenlightening for an LWN article.

This is interesting, in a meta kind of way :-)
(Please: don't take my amusement as a personal offense -- that would be terrible).

You (obviously) don't seem to care for those "messy social problems", and that's OK. OTOH there are people around here who are thinking about why seemingly minor things (Indentation vs "begin...end" or {...}? Init system? Pfft.) have the potential of derailing a community. Often without even bad intentions involved.

I (and it seems some others) found this article very interesting: How does this Simon Lovell work? Why did he do that (he seemed really convinced). What could he have done instead? How was the reaction? How did it pan out?

Somehow there are here several "camps" -- the ones interested in "social stuff" and the ones not. Just like there are (let me simplify *a lot*) the brace-haters and the indentation-haters.

I always had a strong opinion (which has changed over the years). And while I don't really like Python very much, I have a high respect of the people doing it and I've learnt a lot from them (replace Python by most other "communities").

Me? I'm more of a Lisper. Braces? Indentation? Bah! :-)

Things that won't change in Python

Posted Feb 9, 2017 21:42 UTC (Thu) by greened (guest, #52956) [Link] (1 responses)

I read the "Things that won't change in Python" message and frankly, find the justifications lacking. I still cannot get auto-indent tools to work correctly with Python due to the lack of block delimiters. Perhaps I just haven't found the right tool yet. The "C does it bad" reasoning is poor. C's shortcoming is allowing blocks without delimiters, not its availability of block delimiters.

I'm indifferent about significant whitespace. It's redundant given block delimiters but I can see value in the parser forcing indentation to match block structure. Of course the tabs vs. spaces issue is still a major problem. Perhaps tabs should be banned from the language. :)

Things that won't change in Python

Posted Feb 11, 2017 3:00 UTC (Sat) by k8to (guest, #15413) [Link]

The indent-is-structure means that tools can't fully auto-indent. That's just a consequence of the design decision, not a thing that needs solving, unless your solution is a completely different programming language. Which is a completely legitimate choice for you to make for these exact reasons if you think it's really a big productivity issue, but there's no gain in trying to "fix it" in python, because there's no fix. There are tradeoffs of that decision for sure, but people endlessly tilting the windmill of trying to make python be something else on this score is a waste of time for everyone.

That's exactly why this document was created.

With hindsight, leading tabs should probably have been a syntax error, but I feel that this is one of those cases where introducing it now may be worse than leaving it as-is. Personally I'd be fine with paying the cost now of introducing that "breaking" change, because auto-handling in tools is not that hard. However, I'm strongly biased against hard-tabs in source code in general, so I don't trust my opinion here.

Things that won't change in Python

Posted Feb 10, 2017 6:19 UTC (Fri) by rsidd (subscriber, #2582) [Link] (12 responses)

If he hates colons at the end of if/while/for statements, and wants an explicit "end" for blocks, he should use Julia (which is very similar to Python in many ways, these seem the most obvious differences) :)

I also like the somewhat more "purely functional" nature of Julia and the convention of denoting functions with side-effects with a "!" (as in "sort(a)" returns a new sorted list, while "sort!(a)" sorts the list in place. Python is a bit non-intuitive/inconsistent in this respect, eg "a.sort()" and "a.reverse()" sort/reverse in-place, "sorted(a)" returns a new sorted list, but "reversed(a)" returns an iterator, not a list. OTOH, people who like object-oriented programming and hate lots of nested parentheses would prefer python, I believe.

Things that won't change in Python

Posted Feb 11, 2017 3:07 UTC (Sat) by k8to (guest, #15413) [Link] (11 responses)

I agree python's lack of clear conventions on "destructive" methods is one of the unfortunate bits.

I feel the best strength of python is that if you use restraint and keep simplicity as a goal you can approach code that nearly every programmer in the world can read and understand right away. My impression of Julia as a total newbie is that it's targetting a similar space but much more off in the math, matrix, and functional world. There's a good deal that is unfamiliar to me as a general programmer in scanning the example Julia programs I can find.

Things that won't change in Python

Posted Feb 11, 2017 7:09 UTC (Sat) by rsidd (subscriber, #2582) [Link] (10 responses)

Julia is indeed aimed at scientific computing and at people who may otherwise use Matlab. I'm curious, though, which Julia code seemed unfamilar to you as a python programmer. If it's the matrix stuff, Python does that via numpy, but it's inbuilt in Julia.

Things that won't change in Python

Posted Feb 11, 2017 8:54 UTC (Sat) by k8to (guest, #15413) [Link] (9 responses)

Since you asked:

for n = 1:maxiter

I can guess but it feels odd.

v = zeros(t)

No idea, but could look it up easily.

v[i] = trace((P.'*P)^4)

I have no idea, and could not look it up easily,

Q = [a b; c d]

really no idea

m4 = [i+j+k for i=1:2, j=1:3, k=1:2] # creates a 2x3x2 array of Int64

Fairly unfamiliar to me that the expression to the right of the for inside the [] changes the "type" of the [] to be multidimensional. Maybe it would eventually be intuitive, but seems weird that the kind of array I'm getting here is buried in the details over on the right hand side.

by(...)

Just vastly unfamiliar.

I don't think any of this is bad design or a problem really, but it's speaking with a specialised lexicon, imo.
It also has a fair amount of -> going on in a fp manner, which is fair enough but jarring to a typical imperative programmer.

Things that won't change in Python

Posted Feb 12, 2017 3:49 UTC (Sun) by rsidd (subscriber, #2582) [Link] (5 responses)

Heh. The "for i in range(N)" thing is one of my least favourite things about python, and I've been using python for 14 years now. Why not a sensible for-loop construct for the case where you just want to do something N times? Why should range(N) exclude N itself? So I definitely prefer the Julia version. If you do want a range (as an array), "collect(1:N)" does it.

The other points you raise are all linear algebra -- if you don't use matrices you don't need to bother with them, but if you do use matrices you'll quickly find such things indispensable (also, if you are coming from Matlab it will mostly be familiar). For example, the "list comprehension" type thing with three for statements is a multi-dimensional "array comprehension" (something Matlab lacks, as far as I know).

Things that won't change in Python

Posted Feb 12, 2017 10:40 UTC (Sun) by mathstuf (subscriber, #69389) [Link] (3 responses)

> Why should range(N) exclude N itself?

Because it makes splitting a range very easy. There's no need to do an offset to make two ranges that cover 0-2N because you can just do 0:N and N:2N instead of 1:N and N+1:2N (since inclusive ranges tend to be associated with 1-base indexing IME).

Things that won't change in Python

Posted Feb 12, 2017 16:11 UTC (Sun) by rsidd (subscriber, #2582) [Link] (2 responses)

I had kind of assumed that it is so that "for i in range(10):" will execute 10 times, given the 0-based indexing. Your reasoning is, I must say, less convincing to me! It is worse in bioinformatics (my main use case) because most file formats (GFF and similar, in particular) use 1-based indexing and "chromosome:start-end" for indicating sequence coordinates, where "start" and "end" are both part of the sequence. But some (bed format in particular), inspired presumably by python, use 0-indexing and the "end" is excluded. No matter which language you use and what its conventions are, you have to keep the file format's convention in mind...

Things that won't change in Python

Posted Feb 13, 2017 0:18 UTC (Mon) by lsl (subscriber, #86508) [Link] (1 responses)

What mathstuf mentioned is only one of the nice properties. There's a small writeup by Dijkstra that named a few more, IIRC.

https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08x...

Things that won't change in Python

Posted Feb 13, 2017 5:05 UTC (Mon) by rsidd (subscriber, #2582) [Link]

That's very interesting. When I first started using julia I found the one-indexing off-putting. There is a long thread here. The first poster invokes python and a nice box-diagram, but not Dijkstra (whom others do bring up later). Ultimately the Julia argument seems to be 1-indexing is more familiar to mathematicians and more common among mathematical languages (including fortran and mathematica). In practice I have found I make occasional errors (because I am used to python and continue to use it heavily) but it's not as big a deal as all that...

Things that won't change in Python

Posted Feb 12, 2017 12:02 UTC (Sun) by k8to (guest, #15413) [Link]

The logic of the Julia choice is fine, but the *syntax* is not familiar speaking as someone who's written code in all kinds of things from rebol to lisp to BASIC to assembly to TCL too the obvious algol-derived playpen we've all spent far to much time in. It's just an example of the kind of thing it has that makes it jarring to people outside its domain.

Things that won't change in Python

Posted Feb 12, 2017 3:57 UTC (Sun) by rsidd (subscriber, #2582) [Link] (2 responses)

ps: it is also familiar to numpy users, but a bit kludgy in numpy. For example, "zeros" exists in numpy, but the matrix definition
Q = [a b; c d]
would in numpy be
Q = numpy.matrix('1 2; 3 4') # note the quotes
except it doesn't work with variables inside the quotes. The following would work instead:
Q = numpy.matrix([[a,b],[c,d]])

Things that won't change in Python

Posted Feb 12, 2017 12:03 UTC (Sun) by k8to (guest, #15413) [Link] (1 responses)

In both of the python examples, by contrast, I know exactly where to look to find out how to decode the magic, whether it's kludgy or not.

Things that won't change in Python

Posted Feb 12, 2017 16:07 UTC (Sun) by rsidd (subscriber, #2582) [Link]

Well, as I said, this stuff mainly matters to people who use linear algebra, who will definitely appreciate it. Others can ignore it.


Copyright © 2017, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds