I recommend this presentation by Victor Stinner at FOSDEM 2018 which talks about it: https://fosdem.org/2018/schedule/event/python3/
People prefer dumb unambiguous code over clever code. That's why Python and Rails succeeded
If you really think something like that is happening (big if - I’ve gone through so many py3 flames...), the only answer is: because people love the language SO DAMN MUCH that they will overlook its warts. And the next logical step would be to find out how an independent research project, staffed mostly by volunteers and without a marketing budget of any sort (and not running in every browser nor shipping preinstalled on the most popular operating system), ended up with this sort of mindshare.
There might be some good lessons there.
If you look at timing, Python 3 picked up for new projects in 2015, when PSF declared that no new features will be backported to Python 2 from 3.
I believe the industry will wait for 2020 to start migrating existing code after Python 2.7 will be declared EOL.
Perl 5 -> 6 broke all your code in exchange for a whole new language. Some people moved to Perl 6, some to other languages, and a lot stayed with Perl (5), which still runs programs written in Perl 1.
Ruby 1.8 -> 1.9 broke most of your code in exchange for minor cleanups. But Ruby was Rails, so the culture accepted constant rewriting and breakage, and people went along.
Python 2 -> 3 also broke most of your code in exchange for minor cleanups. Users expected some stability, but the language's culture demanded conformity. The result has been a decade-long war in which Python fans try to shame Python users into moving to version 3.
I think that's the most succinct way to put this whole debacle I've ever seen. I'm totally stealing this.
The main reason people switched probably wasn't rails making people expect breakage, the main reason was that (a) it was relatively easy to rewrite your code to work on both 1.8 and 1.9 (as long as your dependencies had already done it), and (b) 1.9 was much faster.
In Python it took 10 years, and even now you can't get companies to migrate, because why make developers do the work when application still can be used. Many places will probably start the migration in 2020, which shows that giving 10 years head start was a mistake and all it did was create FUD and division in the community.
The Python 3 immediately picked up for new projects after announcement that 2.7 will no longer have new feature and only bugfixes in 2015. Industry will wait for the last moment when all support for 2.7 will be ceased in 2020.
The proper way make a major breaking change like python did is to provide a bridge between the two versions, so you could import 2.7 modules from 3.x applications, and even the other way around. As of today there is still no such thing.
Previous versions of python were back-compatible. Java versions stress back-compatibility. I don't know if HN can find any counter-examples, of a language that thrived through an incompatible, code-breaking upgrade.
Python has done everything possible to avoid this fate, by maintaining 2.7. And I'm not even convinced python has gotten away with yet (e.g. kalite, offline khan academy, needs 2.7). RHEL may end up reversing this. Give it another ten years!
Amd the Enterprize is the most back-compatible thing you've ever seen. This change is going to break lots of code, and they will reverse or lose customers.
Counter-example: The ruby 1.8 -> 1.9 -> 2.0 upgrade path. 1.9 introduced the whole encoding system, which was a major update at the time. It did break a lot of libraries that handled strings. Still, the change went over fairly quickly, partly because major players in the ruby world (rails) adopted the change. The update also brought clear benefits and it was clearly marked that 1.8 was going to go out of support. There are still some stragglers (centos 6, I'm looking in your direction), but it's clearly accepted that ruby 2.x is the standard that you should be writing code for.
You reminded me of the java version incompatibility nightmares that once littered the enterprise landscape. If they do that now, it's because their history includes perhaps the worst set of incompatibility jumps of any popular language.
Ruby qualifies, I'd say. From 1.8 -> 1.9 there were syntax changes, changes to how strings worked and so on. Code written for 1.8 would not in general work on 1.9 and the other way around. While it was possible (sometimes with some extra if statements) to write code that worked on both versions I would definitely call it an incompatible, code-breaking upgrade.
But what makes me shocked that you think that that is the case is basic basic stuff... I mean, as one obvious example, they changed the exception syntax. So, "uhhhh.... sure?" it was possible to make a program that ran on both 2 and 3, but it required using "try" with no variable assignment and then digging into Python's exception reflection support to recover the variable. And you had to do this every single time. (And of course a lot of the time the underlying core library would now throw different exceptions, making the situation all the more ludicrous.)
I had code that straddles the 1.8/1.9 boundary of Ruby, and even though I wasn't an expert at Ruby it was trivial to have code that worked for both (and I mean 100% correct: Unicode and everything; remember that neither Ruby 1.9 nor Python 3 added Unicode support, they only made Unicode support easier to obtain. for Python 2 there was already comprehensive, if non-default, support, and for Ruby 1.8 you just needed to be careful about where you did conversions).
What? The PEP that added the new syntax also added it to Python 2.6: https://www.python.org/dev/peps/pep-3110/#compatibility
- if you tried to support Python < 2.7.
- if you tried to support Python < 3.3
But nobody used 3.0, 1 or 2. And supporting 2.6 is like supporting ruby 1.7 and 1.8 and 1.9. Which nobody did.
And it's easy to rewrite libs when really the language started to be used in 2004.
Or maybe not, given that "gem install" still regularly crashes on anything other than the top 20 packages, so it's still not a solved issue.
Only a few like you and me tried it.
I can't recall of any big project or lib ever supporting < 3.3.
They jumped on so early the python devs were saying "WTF are you people thinking?!?"
It actually takes a fair bit of shenanigans to get hand-coded bindings into blender, my last(?) patch was bindings for the kdtree and I had to do some convincing to get that accepted. I'd guess that 99% of bpy is generated bindings.
If they stuck with python 2 when they started the initial overhaul they'd probably still be using it since artists are very vocal when their scripts break.
https://docs.djangoproject.com/en/2.0/faq/install/#what-pyth...
When Python 3 turned up and it was on average slower, my first thought was "well, good luck getting people to adopt that".
Swift breaks every major version at least but not as often and on a large scale anymore with point releases as with 1.x and 2.x. Has been like that from the beginning and everybody that writes it accepted it.
Of course. Swift 3 is one example. Ruby 1.9, as others have pointed out, is another.
PHP is yet another, and perhaps more relevant because it is close to contemperaneous. It had its "Python 3 moment" with the migration to PHP 5. Lots of BC breakages.[0] That transition took about 3-4 years for most.[1] Most users are now on the current major version, 7, and the remainder on 5 are mostly using its latest release (EOL is EOY). No one uses 4.
[0] https://secure.php.net/manual/en/migration5.php
[1] https://web.archive.org/web/20110720002753/http://www.gophp5...
Ruby 1.9 is a great example of why you should not be too nice: they told everybody "you have a fews months, deal with it". The community moved. Python said "poor things, we understand, take those tools and years to do the thing", and the community cried, and did nothing.
PHP literally failed. They canceled V6 and jumped to V7.
The funniest part ?
None of those languages are even close to Python popularity.
Swift is not even used for most Apple codebase. Python supported even Atari.
Ruby and PHP has almost no use case outside of the web. Python is used by OS, on the web, in GIS, by data analysts, for CGI, in AI, for sysadmin, to make GUI, video games...
And Python is much, MUCH older. 1990. 4/5 years older than Ruby/PHP. It has way more technical debt to pay. Swift ? 2014
Yeah the migration was badly handled from some aspects. But honestly, given the challenge and track record of the competition, it's not too shabby.
Ruby 1.9 was working mostly the same as 1.8 while provising 2-3x speed improvment, and new exciting features.
Python 3 breaks even the basic Python 2 hello world, everything was notably slower, and not anything new and exiciting feature-wise apart ubified string support.
Given how much you like Python, I'm surprised at the gall to argue that Python had more technical debt to clean up than PHP did.
When trying to learn it, I encountered incompatible examples and tutorials, complex and changing ways to update it... and then my toy code stopped working. I eventually found the cause of the code-breaking change, fixed it... thought a bit, and decided against ruby. That's just me though.
Python had deep problems that could simply not be fixed without BC breaks. The decision was made, and in hindsight it was the correct decision by Guido and other core devs.
Look at PHP, and look what a total cluster of madness the language has become.
* an optional type system without hacks was not introduced (types in comments, really?)
* the GIL was not removed or at least a solid parallelism story was not included, one that would allow Python to use all cores on a system while sharing, if needed, memory
* no true performance improving changes were made; by this I mean stuff that improve performance by an order of magnitude; Python is still way too dynamic and this basically sunk Google's Unladen Swallow and Dropbox's Pyston, at least in terms of worldwide adoption
I say this because I'm a bit worried that long term Python has locked itself into a corner where it will keep getting pushed into as the other languages develop a better developer UX. Python was a bit lucky to catch the ML train but who knows how long this will last. And Go, Kotlin, Typescript, Swift, Julia, Rust even are improving their ergonomics and edging towards Python's core competency.
How do you do that with out a comment?
a_list: List[T] = []
Visit https://docs.python.org/3/library/typing.html for more information.
vec = [] # type: Vector[float]
vec = [] # type: Iterable[Tuple[float, float]]
a = MyClass() # type: MyClass[int]
x = Foo() # type: Foo[int]
While I really like the concept of PEPs, and I think keeping original (like as they were written) PEPs around are the right thing to do, I do wish sometimes that Python did a better job at incorporating changes from PEPs into the core documentation once implemented.
I'd argue that the fact that it was explicitly a design goal to be a teaching language meant that it saw wide-scale adoption by universities, which made it more likely that someone writing an adaptor library to old linear algebra packages would write it in python.
From what I saw, Python3 doesn't have type hints but it at least warns when you try to do stuff which involves magic, such as trying to increment a float.
Perl6 doesn't warn in those cases. If you use type inferrence it just happily goes ahead and uses the equivalent of perl5 BigNum which makes the code run 50x slower, instead of upgrading to BigNum when int overflows like Ruby does. If you use ugly C-style loops instead of nicer native for loops, your loop will run 2x faster. Too much magic or the wrong sort of magic can be really annoying sometimes.
This is what I currently consider a workaround. At the moment if you have a constant endpoint and it fits in a native int, such as `for ^10`, it is already highly optimized and actually runs faster than the equivalent in Perl 5. That is not done yet where the endpoint is a native int variable. :-(
Not for lack of trying. People have been trying to do this since at least python 1.4. They just haven't found a way of doing it without negatively affecting single threaded performance, which Guido considers an unacceptable trade-off. http://pyparallel.org is probably the most interesting latest experiment in this field, but it never got cross platform support and seems to have stalled out.
That would have broken all C extensions, but it's not like Python 3 at launch was a raving success regarding library porting.
And they continued to break them within the py3k lifetime, mostly unicode related stuff from what I can remember. Probably still break stuff but I haven't had time for my toy python projects in a while so haven't been messing with the C-API lately.
I wished they had broken everything harder and once and for all, in order to fix the issue.
If there's going to be breakage anyway, people adjust their expectations. The scale is basically:
a lot of breakage > a bit of breakage >>>>>> no breakage.
Once you do break backwards compatibility, you might as well do it in a big way, provided you:
* don't offer vaporware for a decade (hello Perl 6!)
* try to offer some mitigations for the migration pain (auto-conversions, support libraries, top-notch docs, etc.)
* offer a great carrot at the end of the tunnel (good performance would be such a carrot)
Fine grained locking works, but is expensive for non-multithreaded applications and slows down Python. It would speed up multithreaded applications though.
You can stop worrying. That is absolutely what will happen.
But it is a good thing. Languages should be something, not merely an accumulation of every fad and trend that appeared over its lifetime. That means eventually they will mature, and eventually hit a peak, and then fade. But during that process, at least you'll have a nice, mature language, instead of one always chasing the latest pretty-shiny, immature, confusing, crammed with too many features, with libraries constantly jerking around trying to keep up and always just a bit broken. Indeed, I kind of thing Python has already done a bit too much of the latter, and were I in charge of Python I'd give some serious attention to the idea of simply freezing the core language.
Python is what it is. Let it be what it is, because what it is is pretty good. It's by far my favorite language of the genre it is in. It's got way too much baggage to compete in the next arena, so let it be the master of the one it is in instead.
Nothing truly dies anymore. It just lives as a ghost and haunts unfortunate journeymen.
"Maintenance mode" should be a badge of honor: you have created something that is a stable foundation for new things. For example, how many programming languages are implemented in anything other than C and/or themselves? Not a lot, and that's a huge compliment to C. Despite its faults, you can probably count on your C program working after you're dead.
Agree 100%. I would have added:
* fix the C API and pass the interpreter instance as the first parameter to all functions as is common in other interpreted languages, rather than relying on a global state.
Being an open community effort gives you a free-pass to make mistakes because you're methodologically sincere. Decisions are made by, and on behalf of, those who use the systems.
Having proprietary interests means you're methodologically insincere: mostly, you sell decisions for the developer but they are mostly for the company.
Agree that there was never a shortage of negative articles about py2/py3 transition. Fairly certain Golang success was down to its advantages more than Python's perception who's use has grown through all this time.
Pretty sure that's not true. Golang might have taken some from Python web frameworks or command line tools, but that's about it. Python's popularity in scientific computing has only grown over time, and that encompasses a lot of fields and users, not just data science.
Absent Go, I suspect many current Gophers would've landed on Python. So in a sense, Python lost people to Go. But I've never seen anything to indicate that there was a large migration from Python to Go, and certainly not because of 2 to 3 or public perception--whatever that means in the context of a programming language.
Python 2 is still the mainstay for Data Scientists. I've seen more resistance to moving to 3 there than almost anywhere. Which is pretty funny because it's the easiest code to port assuming your data science libs support 3 (and all the big ones do.)
I think it's more accurate to say that Go ended up with some of Python's potential mindshare, not that it stole a significant amount of existing mindshare.
The lesson from both Perl and Python is clear: you cannot remove language features - if you do you're creating a new language which has to start from zero in adoption.
What Perl 6 did is change the syntax for various features of Perl 5; while adding a lot of new features.
Any code with a lot of assumptions about text encoding or integer division is going to be terribly broken after 2to3. It very much does require manual intervention unless you're doing very simple scripts.
My point in this conversation has been that this feature doesn't require manual rewrites. And I'd add that in any case the deprecation period for python 2 will have been 12 years once Python 2 reaches EOL. That's plenty of time to update a code base.
https://www.python.org/dev/peps/pep-3113/#why-they-should-go
FTFY. Just think about Perl6, Lua5.3 and VB.NET
I am pretty sure somewhere in this world a miserable soul has to maintain a Ruby1.8 codebase.
Perl isn't as widely used as it used to be. Besides, in spite of the name Perl6 isn't compatible with Perl5 but rather a completely new language.
I don't think the Perl 5 inlines do this.