96 comments

[ 2.9 ms ] story [ 129 ms ] thread
The conclusion to stick to Python 2 just because the author does not like some optional features added in Python 3 seems far fetched.

While the typing thing has been discussed here yesterday[0], I share his views about asyncio.

I was a bit disappointed when asyncio lost its provisional status in Python 3.6. I was hopping that the community will wait a bit more and settle on something else.

The work that David Beazley does on Curio[1] is amazing. This should be an inspiration for the standard library in my opinion.

[0] https://news.ycombinator.com/item?id=13730494

[1] https://github.com/dabeaz/curio

I guess thats the point though, you don't have to use asyncio, in the same way most use requests rather than urllib.
Agreed on Curio. Although async will probably never be straightforward (at least not in the way sequential execution is), grasping Curio is a walk in the park compared to learning the mystical magic of Asyncio. I would also just add, more generally, that while the standard library documentation is extensive, if there is any organisation principle behind it I have yet to discover it.
Python has a history of treating standard library modules as a sort of reference implementation. Look at urllib and urllib2 for example. No self respecting Python dev will use either of those two packages if they can help it. They'll use requests instead. Other examples include Python's standard library json/xml parsers. Nobody really uses them out of the box. In my work, the only standard library module I really use extensively is the collections module.
It's funny I have the exact opposite approach to the standard library. Sure some modules like urllib are really bad and I avoid them, but for the rest when the standard library gives me something I use it.

I often find myself going through the standard library documentation and it's a real pleasure to read and discover things that I didn't know were just an import away.

I use the standard json module all the time and I never felt like it was holding me back. I don't write performance critical software so I tend to value the simplicity more than the performance gain.

In the case of the Json module, I totally agree. I'm not really concerned with Performance either. It's mostly API flexibility that I care about. I mean, urllib is always such a great example of an overcomplicated and inflexible API with bad naming conventions. The Json module really did a good job in learning from previous mistakes. `json.loads()` and `json.dumps()` couldn't be any easier to use. Though, I would argue that the json module's ease of use is owed more to the fact that Python dictionaries map pretty much 1-to-1 with JSON already.
I'm afraid I cannot agree with the sentiment in this . The Python3 equivalent of his first example is no more complicated than the Python2 one he shows. You don't have to use decorators or type annotations. It is there if you want it

> Did Python sell out? I don't know. Maybe Guido caved to some persuasive people with bad ideas. Maybe communists, wanting to reduce global productivity, railroaded through all these garbage PEPs. Maybe Python wanted to throw off its reputation as a toy language and become a serious language like Node.js... Whatever the case, when I look at all the PEPs that have been accepted over the past couple years, I can see that the inmates are now running the asylum.

If you and a billion other people want Python2 so badly, fork it and keep developing it. If the maintainers want to push a language in one way, that is their prerogative! It is their time they are using.

> If you and a billion other people want Python2 so badly, fork it and keep developing it. If the maintainers want to push a language in one way, that is their prerogative! It is their time they are using.

Seriously. If all of the time spent on whining on the Internet about how python3 killed the dinosaurs was used to make a python2 interpreter, a viable fork would already exist.

I mean, there's allegedly a great economic incentive for it, right? All of these business-critical python2 apps are out there, so the whiners claim, you'd think somebody would pay for one if it was actually so much better than python3.

There's a fork that was featured on HN a while back, called python2.8 back then, now apparently it's https://github.com/naftaliharris/tauthon

(FTR I'm one of the folks that think Python 3 is an improvement over Python 2 but we still have a monster 2.7 code base that won't be ported any time soon).

Funny, it seems that, by the standards of the OP, the fork you mentioned is not "Python 2" either. It backported type annotations, async/await, and many more from Python 3. So when are we expected to see a "true" Python 2 fork? :)
What would a fork that didn't add anything to the language look like? Wouldn't that just be Python 2.7?
It could be "just" python 2.7 with security updates / bug fixes, since the official python 2.7 won't be getting them from 2020.
Yeah, that fork gained nothing but negative attention here on HN and Reddit; the general consensus was "why would you do that; Python 3 is so much better". In the face of that criticism, is it any surprise that people are reluctant to create forks?
This all reminds me a fair bit of the transition from VB6 to Visual Basic .NET from about 15 years back.

There was a whole lot of wailing about how the changes were unnecessary, and a whole lot of complaining about how expensive it was going to be to rewrite all this existing code. It was all very visible, but if you paid too much attention to it you'd fail to notice that there was also a huge and quiet majority of people who recognized that VB.NET was a much more capable language that allowed people to easily go places they could barely have dreamed of with VB6. I suspect those people were so quiet because they were too busy doing useful work like keeping their toolchain up-to-date to spend much time griping on the Internet.

So on the Python side of things, it's the exact same story. I see plenty of blog posts and suchlike by people who are still upset about Python 3, but I'm hard pressed to met someone who feels that way in real life. Most folks I know made the switch ages ago, and are a bit mystified that this whole thing is still such a big deal.

Yeah, except VB6 was everywhere and I don't remember the last time I heard about Visual Basic .NET. Perhaps there's a lesson here. FWIW, I've yet to work at a place that uses Python 3 in production, or has any concrete plans to transition.
C# does some useful stuff that VB.NET doesn't, while the only thing VB really did better than C# is COM without interop libraries. So VB.NET ended up just being a bridge to C#, so it died out pretty quickly. I still encounter it a fair bit, but it's usually just the oldest modules in a codebase where everything new is in C#.
This.

I actually use VB.NET at work to strong effect. It enables us to hire domain experts (insurance) and have them working as developers in a week. And you get the full .NET compatibility to networking for updates, PDF libraries, crypto, etc. Everything you'd need for a first class desktop app, with much greater freedom on who you can hire (compared to Java, c#, etc).

But I'd never dream of wanting to build a "weekend app" in VB.NET anymore. You're basically stuck with a very heavy IDE, to fill in boilerplate and do builds. And there's lots of framework churn here so a template you'd have from 2011 would probably be a huge pain to try and implement today.

Never used VB6, but from what I understand it, it was a huge productivity tool: any small task could get coded up and shipped in a day. That's how I think of python right now, I don't want to see it go the way VB. We already have enough enterprise ready type languages, not everyone has to be one.

Surely tauthon should be python6.2 ?

/ducks from downvotes

What's your plan when 2020 rolls in and 2.7 is no longer patched?
Good question. Nobody wants to invest time in the codebase, because it's supposed to be replaced. However judging by the current rate, it won't be gone by 2020.

I guess when 2020 comes around, we'll be shell-shocked to find that python 2.7 isn't supported anymore, and we'll find some unofficial package source for python 2.7 that will keep us afloat for a few more years.

> a viable fork would already exist.

Enthusiasm and passion do not a viable fork make. The number of people who are truly able to grok and work on the core of Python2 who are not already working for the PSF can probably be counted on one hand, without using all of your fingers.

> you'd think somebody would pay for one

And yet such fundamental projects like NTP and OpenSSL show that need and use does not create money for those projects. Instead, those with money or time create their own versions (Apple, Google, BSD).

"Create their own version" means they pay for it, just not by giving money or time to the people who are doing the main project. If Apple, Google etc are paying for their own NTP and SSL versions, that's clearly because it's important to them in some way.

If nobody affected by python2 is going to pay for a python2-fork, python2 must not actually be very important. And yes, PSF might have all the brain trust now, but it's not like a big company whose continuity-of-business really depended on python2 wouldn't attempt to acquire this expertise in some fashion. "Acquire" meaning something as simple as picking a few engineers on staff and saying "learn everything you can about this so we can maintain our own version."

The thing here is you cannot use the name Python with the fork. Think about Iceweasel but without Debian's community.

The new Python fork would have none of Python's fame and it would need some push to solve the chicken-egg problem. Why fork and maintain a huge code base when nobody will use it?

Didn't stop MariaDB did it?
The cases are different.

It was the original maintainers who forked MariaDB off MySQL over a concern for software openness, which sounds like a good reason to fork.

A python2.7 fork will have no reason other than "We don't want to use the new version of the language". I doubt if any Linux distros would replace their python2.7 package with the fork, even after the EOL of 2.7.

I think the point is not that you can't write the first example in python3, it's that you don't see it. When you opened the prototypical python file in your text editor, you would see the first example. Now when you open a modern python file, you see the second. (one can still argue this is an improvement, but it's worth recognizing the point being made.)
If anything, it would look like:

    def hello_world(name: str) -> None:
        print("Hello", name)
Which is completely fine. There'd be no point in using asyncio.
Again, the point is not that you can't write simple code in python3. The point is that you can't write complex code in python2.
(comment deleted)
It's hard to disagree with the author's assessment of asyncio. It may just be because I'm stupid, but I cannot get asyncio to fit in my brain no matter how many attempts I make to learn it.

Another HN thread on python strings got me thinking about the print() function. This is going to sound a bit trivial but bear with me. Although I agree that print() is more consistent with how functions are called in Python, I can totally see how irritating it would be for a Python 2 programmer. It's also just generally disruptive to typing flow: when you've finished typing the word 'print' your hands are 'out of position', making it a bit jarring to type the open parenthesis.

This has me wondering: is there a language out there where deliberate thought has been put towards typing ergonomics and fluency? And I wonder if such a language would have a material impact on developer productivity?

So little time in programming is spent typing that it would make little sense to optimize a general purpose language for typing speed. Reading, modifying and reasoning about programs are much, much more important.
(comment deleted)
> I cannot get asyncio to fit in my brain

I found it extremely (to the point of a frustration-induced mental breakdown) hard. I still can't fit it all in my brain, but I got enough so that my code works. The best explanation I can give is by analogy: think of the kernel of an OS, and how it spreads CPU time across all the processes. Sometimes processes know they dont need to work, say they're waiting for a disk read, or a network message, so they surrender and say "ok kernel, I'm done for now, let someone use CPU". Thats like what the "yield" command does in asyncio, although yield requires a context. So you say "yield until this function does something interesting" (I think it's called 'await' now), then a mini-"kernel" (the io service) stops executing that function and polls all the other functions to see if any of their yields have changed state. It just keeps polling till it finds some work it can do. I dont yet fully grok the futures yet, but I think they're just a way of packaging up the "work item" produced when a yield actually gives you something.

* Disclaimer: I barely understand this, so if I'm spreading bad information I apologize in advance.

I have nothing against asyncio in python, I think its presence helps put python in the "big leagues" of languages, and not just a toy for noobs with arduinos. It's an additional language feature, like C++ templates. You dont have to use it, so the noobs can keep doing their thing. But it prevents more experienced devs from outgrowing the language and having to learn a new one, or port working code to a new language.

That makes sense to me, thanks for the explanation. I don't suppose you do guided tours of the Python standard library documentation? :)

And I get what you're saying about having nothing against asyncio being in the standard lib: I mostly agree. You can ignore it if you don't like it. And it does allow the more skillful python devs to do pretty amazing things (e.g. sanic, that uvloop pgsql driver etc.). I guess the small niggle I have with asyncio is similar to the one have with the standard library documentation (and Gnome, for that matter): I can't understand what the authors/developers were trying to achieve when writing it.

Take the std lib documentation for instance. It's only my opinion, but there seems to be very little consistency between libraries, and much of the documentation reads like a stream of consciousness punctuated by the occasional "oh and there's this thing too". This makes it very difficult to learn about what is being documented.

I mean, that's fine, it's their project and their prerogative and it isn't all bad. But it just seems self-defeating to write documentation that is incomprehensible. I suppose one could view technical documentation as a work of art that has some kind of intrinsic artistic value... Otherwise it just seems like wasted effort to write documentation that doesn't convey information in a useful way.

Sorry this turned a bit ranty. I'm only speaking for myself here; it's entirely possible I just happen to think in a way that is very different to how the std lib doc authors do.

I get what you're saying, that the docs dont really follow an overarching theme. Thankfully, stackoverflow fills in the rest.

> I can't understand what the authors/developers were trying to achieve when writing it.

I can't speak for them, but event-driven designs are a great alternative to procedural polling / event loop designs. I am not sure, but I think there's a relationship to the functional programming style where you say "when there's data, do this to it". So I think what they're trying to accomplish is to enable FP paradigms in python. You could write a coroutine that says "yield until there's data, when there is, transform it".

I used it with zeromq [1] to route messages between a few C++ programs that all work together. So my python program is a "supervisor" task that sends heartbeat messages to my binary programs over zeromq. Asyncio is handy for timing the heartbeats (because you can say "in 2 seconds, do this") and reading the message queue. I also hooked it up to inotify, so I can do "echo SOME_COMMAND > command.txt" and as soon as command.txt is written to, my supervisor gets a notification, reads the file, and processes the command. I almost lost my sanity to get it working, but once I got it, I really like it. One tip though, dont try to mix async and sync programming. Go big or stay home.

[1] http://zeromq.org/

Oftentimes the people who understand the module being documented aren't able to put themselves in a contextless reader's shoes.
I've never had 'yield' explained to me so succinctly :) Thanks!
I can relate to how having print be "special" becomes a habit - but I think on balance, print() is simpler.

Now, going down the rabbit hole of "no syntax" in the end one walks by lisp/scheme and end up at lamdba calculus (or brainfuck...).

Smalltalk has very little syntax.

I've been thinking a bit about how simple is is simple enough for useful computer languages, with an emphasis on reading and writing. The Apl people claim dense notation is good, while I think that "pseudo code" should be enough - syntax is for communicating with humans, the machines have machine and byte code.

Other [ed: "real" languages with rather concise syntax] are Julia, Kotlin and Nim.

I find that using whitespace for blocks (or begin/end) is generally preferable to brackets - we generally only use parentheses in prose and poetry - typing []{}<> is invariably a little complicated with interfaces developed for typing text. @ is actually a little easier thanks to the rise of email (addresses).

I'm biased though, as I generally use a Norwegian keyboard layout - making room for the three extra letters "æøå" exiles [{'< somewhat, which in turn pushes the backtick and a few other "easily available" punctuation marks firmly into repetitive stress syndrome territory.

I've seen Nim pop up a couple of times now. Perhaps I should go check it out (and this Kotlin thing too). Thanks for the leads :)
> Maybe Python wanted to throw off its reputation as a toy language and become a serious language like Node.js...

Is this a serious statement?

It may be a serious statement that shows the author is a person not to be taken seriously.
I think you're overlooking the subtle jab of that sentence. He's denigrating Python 3 by comparing it to Node.js.
He also called Node.js a "language" so I question whether he's capable of that much subtlety.
I read it with a heavy dose of sarcasm, but I suppose it could have been a genuine statement >.>
Surely sarcasm. Surely.
I think that is the author talking about how (in their opinion) Python has gone from an elegant language that a beginner could easily learn, and understand, to a confusing stringy one that is difficult to follow.

The beauty of Python is that you can learn it quickly, and then it can take you anywhere you want to go. That is quite the accomplishment, and that is why it is the perfect language for beginners.

I think the authors statement is meant to contrast those properties with node.js, which imho has neither of the, and is also asynchronous by default; something I think makes it unnecessarily difficult for first-language learners to approach.

(comment deleted)
In latest version of Python it would be:

def hello(name):

    print('hello', name)
I may be in the minority with this here, but I mostly agree with this post. Python 2 is a simpler, and possibly more elegant language than Python 3.

It's true that most of these new features are optional, but that doesn't change that code tends to be written differently in these two languages. I think the relationship between Python 3 and Python 2 is similar to the relationship between C++ and C in that regard.

The goal that all new Python code will eventually be written in Python 3, I don't think will ever be achieved [1]. Personally I'm not using Python much these days, but when I do use it, I still prefer 2.7

[1]: https://semaphoreci.com/blog/2016/11/11/python-versions-used...

> Personally I'm not using Python much these days, but when I do use it, I still prefer 2.7

Why? It mystifies me utterly that people think that having the option to do something is a burden. What is it about asyncio just sitting there in the stdlib that you find heinous? I don't use the shelve package either, but I never thought "I need to find a language where I can't easily import this monstrosity".

The fact it's there means you'll probably come to a point where you'll have to interact with it by way of someone else's library, unless you NIH everything.
Is the alternative of interacting with some other, less supported/ubiquitous/documented package preferable?
Perhaps not. All I'm claiming is that an "optional feature" isn't as free to avoid as one might think.
Sure, but I don't see it as being more evitable than any other popular library.
I don't understand this sentiment at all.

What does Python3 require of you that isn't necessary in Python 2? Print as a function is my only example.

Python 3 lets you continue writing the same same simple stuff as ever. It also provides a bunch of other power that you can _choose_ to use.

The OP's example is such a strawman it's hard to take seriously. If you're writing little scripts (or teaching someone some introductory programming) You don't need to use decorators or type annotations or asnyc/await. If you're Dropbox and you've deployed 4 million + lines of Python, then maybe type annotations make sense for you, and there they are.

What is there about 2.7 that you prefer? The thing that most surprised me after finally moving to python 3 full-time a few years back, was that it was so completely painless.

That's true as long as I'm the only person working on the code. What happens when I need to collaborate with others? Am I gonna be the one to say (the equivalent of), you can't submit this perfectly valid and idiomatic C++ code, you've gotta remove all the templates first?

Choosing Python 2 when I can is like setting in place a simpler coding standard.

>I may be in the minority with this here, but I mostly agree with this post.

Which part of this incoherence are you most fond of?

* The part where he gives an example of "simple" python 2 hello world and pretends that the equivalent python 3 isn't exactly the same thing with two added brackets ( ) ?

* The example he does give instead which isn't even valid python.

* The part at the end where he gets confused between type safety and static typing and declares a preference for C based upon that.

I upgraded from 2 to 3 last year. I'm liking it.

I've embraced type hints. Although they have no run-time effect, there is a command line tool called mypy which enforces correctness. It has caught more than a few errors for me. Declaring the types of arguments and return values is a help when reading the code imo.

This. Running a script which takes hours to execute, only to find you have a TypeError on the last line just before you get the results you need is really frustrating. Static typing is a must-have imo.
(comment deleted)
This might be hyperbolic sarcasm. If not, it's silly. Nothing to lose by not giving it your attention.
This post screams of python 2 whining and the like with a general unwillingness to evolve with the language.
Isn't it great there are enough languages that everyone can be happy?
That was partially the author's point. However, he came from the other direction: If you want a statically typed language with powerful asynchronous tooling then maybe Python is not the right choice. There are already languages that are great at that. So why make Python that's already great at being Python less good at being Python and instead into something that other languages are already great at?
Being the annotations (and asyncio) optional, how would that make the language any worse?
Node has a similar thing with these "async" commands and such. You don't have to use them.

Python 3 is where the world is moving to, doesn't mean we're all turning async.

> The garbage fire that is asyncio dramatically increases the complexity of the language. Despite asyncio being just one module among others, one might as well consider it built-in, because it is integrated so deeply in the object model and syntax.

I don't quite understand. You can easily use Python without knowing asyncio exists. The last time I ever thought about asyncio while programming Python was when I was using asyncio.

What happens is people realized that python is not reliable enough for serious business applications and they to fix that.

After experiencing static typing with TypeScript I don't really want to go back to dynamic typing.

>After experiencing static typing with TypeScript I don't really want to go back to dynamic typing.

Javascript's main failing wasn't a lack of static typing it was a lack of type safety (which statically typed C also suffers from). Python didn't suffer from this.

If you tried to convert an invalid string to an integer it won't just try and have a bad guess at what it thought that you meant (C, Perl and JS's default behavior), it would raise an exception instead.

No the problem is when you have a method that takes three parameters you want know what these parameters are and what you can do with them. Trying to figure this out in a dynamically typed language is not fun.

In TypeScript (with a decent editor, like VSCode) you just hover the parameter and you can immediately see what it is.

>Trying to figure this out in a dynamically typed language is not fun.

Sure it is. Fire up the IPython REPL at the point in the code where you're intending to use it and experiment. Not only can you see what it takes, you can see what it does in real time and you can experiment on the results.

>In TypeScript (with a decent editor, like VSCode) you just hover the parameter and you can immediately see what it is.

Well, you can see that it's a string of some kind.

I don't generally flag articles, but this one is so pointless and inflammatory that I had to flag it as flamebait.
Have you checked out who the author is?

I am not sure it qualifies as flamebait. The situation may be a bit more nuanced. I first read some of the comments in this thread, then went and read his article, then came back here to read some more comments.

Charles Leifer (per his resume [1]) is a co-creator of readthedocs.org (where the docs for a lot of Python OSS projects are hosted), and of the PeeWee ORM (which I know of and have used a bit).

[1] http://media.charlesleifer.com/blog/documents/resume.pdf

He also writes a lot of (technical) Python posts on his blog. I've read some of them in the past. Unlikely that a person like him would be interested in writing such a post as flamebait.

I'm guessing the post is describing his genuine thoughts / feelings (right or wrong) about Python's evolution of late, even if some of his points may not have been well-thought-out, per what I read from some comments here. I haven't gone into an analysis of what he wrote vs. the comments here, in depth. But I think we should cut him some slack, and not flag the post as flamebait. Just my 2c as a Pythonista and HNer.

I guess my characterization of "flamebait" was unfair in that it implies intent. I actually meant "inflammatory", because the post makes a huge deal out of what is, in my opinion, not really so bad.

I even agree that asyncio is a clusterfuck, but we're free to use Curio (which looks much better), and if you don't like how complicated type annotations make the language, don't use them. I agree that they've been bolted on rather clumsily (having to import the type system feels weird), but it's nowhere near as big a deal as the author makes of it, and I feel the post makes mountains out of molehills.

tl;dr If you use Python 3 in ugly ways, it will be much uglier than if you use Python 2 in pretty ways.
This is pretty exaggerated. I've been in coding in Python for more than 10 years and I only rarely encounter code that suffers from the issues this article complains about, including Python 2 and 3. And the reason, of course, is that this article focuses on complex cases like chained asynchronous functions and optional type decoration but criticizes them as though they were representative of typical Python code.

Yes, if you want to write a system of asynchronous functions with type decorations, then yes it can get a little messy. But this isn't Python becoming less "austere and easy to read" over time, this is just identifying a case where Python is less readable than one might like.

I'm not sure what to tell you if you were looking to write asynchronous code without some amount of syntactic cruft. There are languages that can do this with a prettier syntax and less boilerplate (Go, maybe). But I don't think has ever included any version of Python.

Not to mention that it'd be even more messy if you were to add type annotations and async in Python 2.
I put off upgrading to Python3 for a while because I was working on a codebase that had dependencies stuck in Python2. After moving on to the next gig, I started using Python3. Differences? Python3 has many nice optional features, and it fixed the unicode issues. That's it. People act like this is such a huge thing when it is not.
Yeah, async is madness. The part of asynchronous and reactive mass-hysterias.

Very few applications really require AIO and/or coroutines, and spawning a coroutine for each I/O request is a madness indeed.

Last but not least, such kind of API should be general and minimalistic, the way Erlang does its processes. Or how Plan9 does I/O via general protocol. Unfortunately, Python guys are looking in a wrong direction (is that C#?) for inspirations.

Just come to Perl6...has all the nice things Python3 has plus a bunch in a really nicely designed package. Seriously, it is much prettier than the linenoise people think of with Perl5. The only problem is the implementation is very young and immature (but it gets daily fixes and improvements). Perl6 is a completely new language designed from the ground up over 15 years. It has some syntactical similarities though. Sometimes I wish Python would do the same thing and start over on LLVM like Crystal, or do something closer to Perl6. If you just want a simple scripting language, Lua and Rebol are nice and Red (when finished) will be like Rebol on steroids.
Interesting. What online resources and books would you recommend to learn Perl6?
There is an excellent Perl6intro tutorial out there for a lightweight overview along with learn x in y minutes to start. Diving deeper, there are several books that either just came out or are about to come out. I think they have links on the Perl6.org site. In particular, there is a recent O'REILLY release that you can read now, but still has a month until the paper edition is finished (Think like a Data Scentist with Perl6 by Laurent Rosenfeld) and it is very good as something that covers a lot, but not too crazy. Brian d Foy had a successful kickstarter to do a Learning Perl6 book (he has written several versions of Learning Perl5). There is a rumor that Larry Wall is working on a Perl6 version of his Programming Perl (Camel book). Probably one of the best resources is Rosetta Code. I really like how you can still use it for quick and dirty code, yet still write beautiful OO or FP code. It has what they call gradual typing in that it is dynamic like python, but you can add types to functions that help to catch lots of errors. Curtis "Ovid" Poe gave a Perl6 talk (slides and video online) that show how you can take something like the standard recursive Fibonacci sequence and restrict the input to an int that is greater than or equal to zero (it can even be more powerful than that). Despite what some might call feature overload, I've been pleasantly surprised by how easy parts are to grok and how well it fits together. Grammars as part of the language are especially cool. They've even built grammars to parse and execute Python, Lua, Perl5, and Scheme. So you can essentially use any Python library in your P6 script.
Thanks a lot for the detailed answer and resources - will check them out over time. I had bought the Camel book and had read most of it, years ago. I know Curtis a bit, nice guy.

>It has what they call gradual typing in that it is dynamic like python, but you can add types to functions that help to catch lots of errors.

Is this something like in Haskell, where I've read (not sure of the details) that you can define types related to the parts of the application or business domain / business logic, which then enables more error-checking by the compiler when you use those types in your code? It may be things like instead of using just an int, if it is meant to represent say height of humans, you might add constraints like height > 0 and height <= 10 feet (because you think or know that no human can be taller than that). Then the compiler will warn you or give an error if you try to assign a value to a height variable, which is outside that range.

Pascal has a version of this feature oo, but maybe Haskell has more support for this stuff - not sure.

Never got too far into Haskell despite reading up on it several times and writing a little code, but adding constraints does sound exactly like this. One of the prototype P6 implementations was written in Haskell, so P6 stole some features. The only thing I'm not sure about is Haskell does this at compile-time and P6 does this at run-time I believe.
I suspect the debate about Python3 will never end. My thoughts on this are:

- Python2 seemed to enjoy some success because of its simplicity

- Python3's breaking changes seemed ill thought out. As an example, PEP-414 [1], which reintroduced explicit Unicode string literals to ease porting Python2 to Python3. The fact that it was removed in the first place suggests there was a lack of thought about or concern for the effects of breaking changes. It's almost like once the decision was made to make breaking changes then considerations about porting and libraries maintaining compatibility between the two were of no concern.

- IMHO there has been a shift away from dynamic languages that came at a rather bad time with the schism in Python land.

- Non-backwards compatible changes have often gone badly. Perl5 to Perl6. PHP 6. Python 3. I mean gone badly in the sense that it seemed to hurt adoption, at least for awhile.

- It seems like statically typed languages have somewhat supplanted some of the use cases for these languages. I'm thinking of Go as one specific example. The way I like to put it is that dynamic languages force you to have unit tests for spelling mistakes and typos.

If you compare the Python3 async stuff with Go's I honestly think Go is more elegant here.

- Lastly of course there's the GIL. I think this is increasingly becoming a problem in a multi-core/multi-threaded world.

The GIL design really does simplify writing C extensions. This makes Python pretty convenient and well-suited for certain tasks. I'm thinking specifically of things using Numpy.

Anyway I'm not saying you can't write, say, high-performance Web servers in Python with AsyncIO/gevent loops and the like. It's just not as... elegant and simple as things seemed back in the days when Python 2.7 was state of the art.

[1] https://www.python.org/dev/peps/pep-0414/

I have extensive experience working with Python 2, 3, asyncio and gevent so I'll comment on some of the points in this article.

Python 2:

    def hello_world(name):
        print 'Hello', name

Python 3:

    def hello_world(name):
        print('Hello', name)
> The language, which was once simple and elegant, has become complicated and clumsy

Python 3 is just as simple to use as Python 2 (simpler, even due to all the cleanup that happened - just think about the encoding mess in Python 2).

What happened is that new, powerful features got added to Python 3 that solve specific issues that people were having. It's entirely optional to use these, but they make life much easier if you need them.

Async programming is only really applicable to highly concurrent network programming or other applications that spend a lot of time waiting for IO. For everything else it's just unnecessary overhead. It is inherently complicated. In particular, the async/await paradigm is extremely powerful. I first encountered it in C# and immediately fell in love with it, and I'm happy to see major languages like Python and JavaScript adopt it. It makes clear where you hand off control back to the event loop and prevents all sorts of bugs where you'd accidentally block the main thread by invoking blocking IO.

gevent, in comparison, is an ugly workaround that hides all of the complexity behind async programming. By monkey patching all IO libraries to be magically async, it makes it impossible to reason about the execution flow and it's extremely easy to get it wrong. That is an affront to the Zen of Python (Explicit is better than implicit).

Type annotations are just a standardized way to do what large projects were doing anyway - documenting types. By moving it out of the docstrings and formalizing it, it opens the door to strict type checking. The resulting ugliness reflects the difficulty of typing a dynamic language and you only need it if you want strict type. You can write untyped code just fine.

> I'm not even debating the value of type annotations [...] And why do this when there are hundreds of other languages out there that are statically typed?

Do I have to point of the irony?

I will start liking python 3 once print(str(b'hi')) will print just 'hi'

That is: UTF-8 should be the default encoding, at least let me specify it somewhere.