Python 3.0: What’s The Point?
Python 3.0 is finally out. I like Python (though it and Ruby are always competing for my affections), and I’m always a sucker for new features in any language, but I’m having trouble getting excited about this. Despite the longtime code-name “Python 3000”, it doesn’t seem very futuristic; and it introduces a lot of compatibility problems. In fact, after reading the docs, I can’t come up with any good reasons to install or use the new version. Am I missing something?
Looking at the official What’s New page, my takeaway is that the benefits are:
- A bunch of minor language features cleaned up
- Better (at least less confusing) Unicode support
- Some nice but minor new syntactic features
while the drawbacks are:
- Won’t run any pre-existing Python software. Just one minor example: the xrange() function no longer exists; instead, range() behaves the way xrange did. I’m pretty sure I’ve written something like “for i in xrange(a,b)” in every significant Python program I’ve ever written, causing all of them to break in 3.0 until I update them. Which is trivial; but there are dozens and dozens of changes like this. And many of them won’t cause easy-to-diagnose exceptions like the removal of xrange; some just cause subtle changes in behavior that will likely require debugging if they’re overlooked. (There is apparently an automated code converter, but of course it won’t fix everything.)
- As a side-effect of the above: All existing Python books are now out-of-date. (Sure, much of each book’s coverage is still accurate, but the reader who’s not a Python 3 expert already won’t know which parts are OK and which are now wrong.)
- Programs written for Python 3.0 probably won’t run in any earlier version of the interpreter, since most of the changes aren’t backward-compatible.
- Slower performance: “Python 3.0 runs the pystone benchmark around 10% slower than Python 2.5.”
Something seems wrong here! the benefits are minor, the drawbacks are huge. Where’s the incentive to use it?
Compare this to the Ruby 1.9 story: A number of language improvements; they’re mostly backward-compatible, although with enough exceptions to break lots of large apps like Rails). But oh yeah: it’s three times as fast. That’s a very big deal, considering the poor performance of today’s Ruby (and Python). Once the 1.9 tech appears in a stable release, I am definitely upgrading.
Or compare to an operating system upgrade. How would you respond to a pitch like: “The ‘Meerkat’ release is going to be incredible! We’ve made a number of improvements to the system libraries. Of course, all existing apps will break, so you’ll have to get upgrades from the developers (which won’t run on earlier OS’s, by the way.) And afterwards you’ll notice everything running 10% slower! But we’re sure you’re going to love the enhancements to iterators and Unicode support…”
So what did I miss? I don’t mean this as an attack; I’m just genuinely confused…
Update: See also my further thoughts in response to James Bennett’s article.
December 5th, 2008 at 4:50 PM
Jens, as a Python developer I think your comments on this are valid and important. I remember some of these points (especially the forking of the Python community) being brought up long before the Python 3.0 release, but I feel they haven’t been listened to as much as they would’ve deserved.
My own thoughts on Python 3.0 release here: http://www.cmlenz.net/archives/2008/12/py3k.
December 5th, 2008 at 4:57 PM
It seems to me that many of the comments being made here are likely to have been made without benefit of any real experience in Python 3 or porting to same.
I’ve just finished doing some testing in support of a web application development framework and object database package(s) which in its latest release this week to coincide with Python 3 now supports Python >= 2.4 and yes, that means Python 3 as well. Same code. And it wasn’t messy at all.
It was a pretty clean base of code beforehand, which has certainly made it easier to move it to 3.0 compatibility. Preserving performance is a big, wet, red herring, depending of course on what you use the language for. In my case, Python 3 turns in performance equal to 2.5.x which I run on our production machines (although not for much longer).
(your mileage may vary)
December 5th, 2008 at 5:07 PM
BTW my comment above was not directed at Christopher. His comment in his journal entry about third party applications and libraries is dead on.
(and I think part of my post got truncated - see http://mikewatkins.ca/2008/12/05/why-python-3/ for a discussion on why I think performance is something of a red herring, at least for some applications)
I particularly miss documentation tools such as docutils, pygments - hopefully there is a move to see them show up in compatible for forked versions.
December 5th, 2008 at 5:45 PM
December 5th, 2008 at 5:52 PM
“but I feel they haven’t been listened to as much as they would’ve deserved.”
I was worried about this too, and that was the feeling I got when it was discussed. But that fact is that after the big discussions about this, much more backwards compatibility has been put into 2.6, and when I pointed out the last major hurdle for a smoother transition and 2.6+3.0 compatibility, that was fixed with a new future import in 2.6 within a week or so after I reported it.
I also then the points are important and valid. But I think they have been addressed. It is perfectly possible to make a transition from Puthon 2.5 to 3.0 via 2.6 and support two python versions at a time, from the same code base.
A fully testable set of code examples is here: http://code.google.com/p/python-incompatibility/
It’s not complete, and I very much welcome contributions.
December 5th, 2008 at 6:00 PM
Er, this post is the definition of “concern trolling”. 2.x is still going to be updated (including “security fixes”) for a long time, anybody who actually used the 2to3 tool in the last YEAR agree that it works very well, and you have another YEAR to start thinking about porting. As somebody else pointed out, even a big app like Django already works with it, and they introduced the compatibility right in the middle of a huge release push. As *major* language transitions go, this is pretty darn sweet, and it was announced and planned well in advance. Hell, Mak Summerfield had the “Programming in Python 3.0” book ready 9 months ago, and he’s not even a developer or an “insider”!
Thanks for the stop-energy anyway, I could have recharged a Prius with it :)
December 5th, 2008 at 7:09 PM
Here’s what one group did to “port” (co-exist) their 2.x applications such that the same code base runs on 2 and 3.
http://mail.mems-exchange.org/durusmail/qp/441/
December 5th, 2008 at 7:32 PM
I like this “it’s totally possible to write code that works in 2.x and 3” argument, which GvR himself has taken the time to refute: the what’s-new doc specifically instructs developers not to do that.
December 5th, 2008 at 7:52 PM
Your comparisons are entirely unfair for a start. Operating systems generally are not fully backwards compatible. If you upgrade glibc, you will have to recompile your software, and there can be problems. Every major release of Windows has been a bit slower than the last version and quite backwards incompatible to boot. Every release of OSX has given people major headaches with what things they put in or took out from the previous version.
And then comparing to Ruby 1.9 - just going by the version number makes it clear that these aren’t the same type of release in the slightest. 1.9 infers that it is most likely the final and most polished release of the 1.0 line, intended to be backwards compatible, and optimized as much as it possibly can be. 3.0 on the other hand, is a bold step in a new direction. No it’s not perfect. Sure there are flaws. That is what 3.1 and 3.2 are for.
December 5th, 2008 at 8:11 PM
I believe the 2to3 tool is supposed to help with the migration significantly.
I would also speculate that it will be much easier to start a new project in Python 3, rather than convert your old ones over. Similar to garbage collection in Objective-C.
December 5th, 2008 at 8:19 PM
@patrick: Actually, no, Ruby uses the old Linux version number model. 1.9, being an odd-numbered release, is an experimental branch. 1.8 is currently stable, and 2.0 is the next stable branch. Someone up the thread claims there’s some confusion about this within the Ruby community; I’ve not seen any, it’s been sold this way from the start.
Ruby 1.9 is exactly equivalent in release status to Python 3.0 if what you are saying about Python 3.0 is true.
And I can’t make heads or tails out of your “OSX major headaches” comment. I assume you’re a Windows user?
December 5th, 2008 at 8:20 PM
I guess I should add that I’m as impressed as Jens is with the new language — this is what you break compatibility for? Really?
December 5th, 2008 at 10:40 PM
/me shakes head. Unicode is a *real world*, everyday problem, that tons of us have to deal with. Some of us are parsing terabytes of text data with Python… and Unicode has been a *huge* pain point.
December 6th, 2008 at 12:52 AM
So, one of these comments mentioned Perl as being an example of Unicode done wrong, and I can’t bring myself to let that kind of misinformation stand uncorrected.
Perl has had almost magically great Unicode support since version 5.8, many years ago, and far better than Python until 3.0 (and without breaking backward compatibility). A Unicode string in Perl is…a string. All data types can contain Unicode transparently, and you never have to think about Unicode, at all, unless you’re interfacing at the binary level with other Unicode speaking software and you need to all agree on an encoding, in which case the “use utf8” pragma (and related pragmas) make it as close to automatic as can ever be expected. You can even write code in Unicode in Perl, if that’s what floats your boat.
Perl has its flaws but Unicode support is definitely not one of them. It is one of the things that I would say, with confidence, that Perl got right many years earlier than Python or Ruby.
December 6th, 2008 at 2:34 AM
“GvR himself has taken the time to refute: the what’s-new doc specifically instructs developers not to do that.”
In fact, that documentation is outdated and incorrect. It for example says that you have to avoid using print, which was true a year ago, but is not true any longer, after from__future__ import print_function was implemented.
So that is a bug in the documentation, quite simply. I’ll submit a bug report. As mentioned above, I have a project to document the incompatibilities and provide workarounds. I have so far not found anything that is NOT possible to make work under both 2.6 and 3.0, although admittedly, it’s not complete yet.
http://code.google.com/p/python-incompatibility/
December 6th, 2008 at 9:58 AM
Just to congratulate the site and its readers.
The site: very interesting, sober and clean design.
The community of readers: is not frequently to find such an interesting, educated and civilized discussion of ideas.
It is a pleasure to read this comment thread.
Thank you.
December 6th, 2008 at 10:33 AM
Guido can do whatever he wants with his language, but I do wish he’d stop hiding behind that “one obvious way” mantra he trots out as justification for some of his more ridiculous decisions to be different just for being different’s sake. Where were you the first time you had to delete a directory in Python? How obvious was the solution?
Like every other kid who walked around school memorizing a dog eared copy of “All The Words,” he wants to be noticed more than he wants to make anyone else’s life easier, and any form of negative feedback received as a result is reinterpreted by his ego as affirmation of some divine mandate. Praise is touted as evidence of Python’s superiority, and critics “just don’t get it” thereby proving the Python way superior again. No point in arguing; like it or lump it.
Either way, nobody’s forcing anyone to use 3.0 and I’m sure the “Django Ecosystem” will get along about as well as it ever has. If you’re unhappy with the directions the project is taking just wait five years and something else will come along that makes some other fat guy with a stupid haircut start espousing drivel like “We will never be able to make real progress in computing and language design in our industry until Python/Ruby/Ocaml/Lua/Erlang syntax is wholly eradicated.” There was a universe before Python, and there will be one long after it’s gone. Use it for what it’s good for and put it away when you’re done.
December 6th, 2008 at 10:59 AM
The first time I ever needed to remove a directory in python was just now (I usually store my data in ZODB).
So, I create a directory with lots of files in it, and to make it more difficult, subdirectorries, with files, and start up python.
>>> import os
A dir of os provides a removedirs method, that complains that the directory is not empty. OK. Fine. There is also a os.listdir. So, I dir(os.path) and find an isdir method. An obvious solution appears:
>>> import os
>>> def removetree(path):
… for filename in os.listdir(path):
… filepath = os.path.join(path, filename)
… if os.path.isdir(filepath):
… removetree(filepath)
… else:
… os.unlink(filepath)
… os.removedirs(filepath)
>>> removetree(‘removeme’)
That worked. I did one mistake, in the first typing in of it, I put the os.removedirs inside the is is os.isdir tests, so the top directory didn’t get removed. Other than that, my first try worked straight off. It took me just a couple of minutes to do this, test it and wrote this comment.
Code speaks.
December 6th, 2008 at 1:20 PM
Totally? Really? This is just the kind of convenient misinformation that obstructs any dialogue involving criticism of Python 3. It’s a bit like people saying that there was no convenient way to get an abstract syntax tree in Python versions before 2.6. Total fiction!
In what way was Python 2.x Unicode support not “real”?
Of course it has! Python 2.x and 3.x are divergent code bases. People will try and backport stuff to Python 2.7 in order to persuade people to really start using 3.0, but we’re talking about two different languages with decreasingly related implementations from now on.
December 6th, 2008 at 1:54 PM
As you yourself mention, there will be more backports. So in fact, they will have *increasingly* related implementations from now on.
And it’s not two different languages. There are a set of changes done that are done in a backwards incompatible way. That doesn’t make it two different languages. The languages does not fork, unless the community forks. That *is* a risk but one that has been greatly reduced with the possibility of gradual migrations via 2.6 (and maybe 2.7). And it has in any case not happened yet,