124 comments

[ 4.2 ms ] story [ 135 ms ] thread

  The problem with Python is of course that it is an interpreted language with lazy evaluation […]
Huh?
They probably mean dynamic.
It doesn't bode well when an article starts with such a gross misuse of a technical term.

Far from me to defend Python, but this rant didn't start well.

Came here to make that exact comment. But I didn't see this comment, so I said the same thing.
Terrible is using a dynamic programming language and expecting static features from it. Besides, linters and type hinting have come a long way.
They have, but I find they still lag behind the state of the art. Python insistence on optional, second thought support for type hints is frustrating.

Linting has saved my bacon more than once, granted.

Still incredibly horrible for many cases. And very slow compared to things that have been around for decades. Do some ocaml and you see how incredibly bad everything 'linted' is. You can compile millions of lines in seconds in ocaml, eh delphi on a 90s computer, jai (I don't find Blow sympathetic but he does point out how lame everything is and that's good) etc, but when my 50k python or typescript project starts linting when doing a yarn build, I have time for a good workout.

Ocaml is an interesting example imho, as the type inference engine is so good you hardly have to specify types. When you read it and squint, it looks dynamic. It's not.

>Besides, linters and type hinting have come a long way.

You acknowledge that the kinds of static analysis that are feasible in Python are valuable, but it's "terrible" to want the kinds of static analysis that are infeasible. How interesting that the two boundaries line up exactly.

If you want static typing, typically you want to avoid python.

If you want the freedom to easily mangle json or other dynamic types, you'd enjoy python.

Yes, pretty much agree with this word for word. It is very, very difficult to refactor a python application in any sort of reliable way. The standard way of error handling in python appears to be to present the user with a stack trace. Very user friendly (not!). Now people will say that, for instance, mypy can help with this. That is true but since projects can be started without type checking chances are that your project was started without type checking and that introducing mypy is somewhere on the backlog and when it comes off the backlog it will be enabled only partially because otherwise there will be too many errors and so on. It is such a garbage programming environment.
I couldn’t (and still can’t) believe that non-exceptional situations are considered exceptional. Such as, there not being a way to parse a string into a number and return a value indicating if it was successful or not. With Python everything is an exception. Messy and inelegant. Of course this mess is called “pythonic” so everything is fine…

https://blog.codinghorror.com/exception-driven-development/a...

https://stackoverflow.com/questions/2184935/performance-cost...

Whether or not you agree with it the argument for exception handling, rather than return values, is it lets the code more naturally flow for the successful case. The alternative is go's repetitive

    f, err := fn(...)
if err != nil { ... }

pattern. Which is better is really a matter of taste. To have error handling smattered all over the code seems more inelegant and messy to me.

What? You can return Exceptions instead of raising them. Since the language is dynamic, the caller can introspect.

Personally, from the perspective of a number parsing function, I think being passed an unparseable number counts as an "exceptional" situation- InvalidArgumentError- and I don't care which way it's returned- as an raised exception, or as an error object- as long as it's clearly documented, and the use matches the semantics of the function (NetworkNotAvailable is a better example of an exception where you're want to put something in the exception block)

> The standard way of error handling in python appears to be to present the user with a stack trace.

What do you expect it to do? Silently fail and move on?

No. How about something that is neither "silently fail" or "print a stack trace"? How about something that lets the programmer handle the error?
Yea python should introduce try except.
Python has proper error-handling since 20+ years.
>forked worker processes to handle requests

File this one under "things that UNIX systems programmers think will work in principle but end up being massive black-holes of attempting to quiesce any non-trivial application in a way that results in a sensible post-fork state".

(comment deleted)
Python is one of my least favorite languages and I avoid it wherever I can. I agree with several of the criticisms here, but I disagree with this part:

> The problem with Python is of course that it is an interpreted language with lazy evaluation

That isn't "the problem" with Python. There's nothing wrong with these sorts of languages. However, it does limit the sorts of problems the language is suited for, and I do see places where Python was used where another language would have produced far better results.

Perhaps using Python inappropriately leads to some thinking that the fault is with the language?

> with lazy evaluation

I know it has functions that are lazy, but it's not lazy as in a sense that Haskell is right? I never use it as I find it a ghastly horror show (my taste, other people like it, that's fine), but I had to use it a few times and found that (also from the article) some parts are lazy, but not python as a language. Is that not correct?

> it does limit the sorts of problems the language is suited for,

Interpreted (...) is the implementation, there is no reason why it should be interpreted.

Almost surely the author of TFA meant "dynamic", not lazy.

Nobody uses "lazy" in the sense of TFA.

The article meant Dynamic instead of Lazy? Ah.. Well, that's terrible use of words that mean something then.
Yes and yes.

It doesn't bode well for a bit of criticism when it starts by grossly misusing a technical term.

It’s just plain wrong. The Wikipedia link points to “lazy” in the Haskell sense. Python is not that.
Agreed. It's so evidently wrong my guess is that the author thinks "lazy" means "dynamic", searched Wikipedia and pasted a link to the article without reading it (in which case he would have found it didn't match his understanding).

It's the less insane explanation. The alternative, that the author read and understood what lazy evaluation is, but somehow still thinks Python does it this way, is too crazy to consider.

(comment deleted)
You are right, the article is wrong. It is most certainly not lazy. f(g(), h()) will always call both h and g regardless of whether f uses their results.

Iteration in a sense can be "lazy", but that laziness is via data structures built on top of a strict core language. Python is not alone in having lazy iteratable data structures, but it leans into them relatively hard in its standard library.

Many of us love this, as it lets for loops work elegantly over all sorts of abstractions, but I could see some folks disliking it. Still, the author does not explain this nuance, which makes me think he does not quite know what he is talking about.

Almost every mainstream language has a way to "lazily" (in the sense you mean) iterate over lists, so this can't be what the author was singling out. I think he's just confused.
But that's just libraries though. A language that actually evaluates outer to inner is different. And yes, indeed confused I would say.
Not Haskell style lazy but more of declarations are just another statement that aren't evaluated until those lines are executed. This means you can have function definitions inside of ifs which can be very useful for conditional programming / meta programming. Similarly, all variable accesses happen at runtime. This makes it so you can't truly statically verify the program but that the only way to know for sure how it will behave is to run it.

In an odd twist, function argument defaults are evaluated at function definition execution time rather than call-time (so half-way in laziness) so a `[]` as a default is shared between all users of that function and if you modify it you are changing a global. I heard that this led to a vulnerability within some security software.

What you describe is not lazy evaluation in any accepted sense of the term. I bet you it's also not what the author meant; he was probably thinking of dynamic typing.

Alternatively, maybe the author (and you) meant "interpreted language"? Lazy/strict evaluation is an orthogonal aspect.

I have developed insanely complicated software with Python that works pretty well.

If you expect to find Java or C in Python you are looking at the wrong place.

And now, of course, it's deprecated because you wrote it in a version of Python that's no longer in support or used a library that hasn't been (or maybe won't be) ported to 3.11.
I did 2 to 3 migrations. It was fine. I would rather deal with these types of issues once in a while than work everyday with Java.
Yeah. I did 90kloc of python porting. Twice. Never working for a company that allows developers to use python again.

I'm glad you were able to port your scripts, but python is absolutely not appropriate for mission critical software.

> And, not to put too fine a point on it, but if you can code Python but not Go (or another decent programming language), you probably have no business writing software for a living. I know it sounds harsh and I apologize for that, but writing software is a profession and hence you should have the knowledge, skill, and experience to use professional tools.

Part of the profession of software engineering is maintaining software that's already written. Should the people who maintain python code, not be paid for their work?

Another part is choosing the right tool for the job. Python has its flaws, but it is better than Go in some ways. For example, it has a richer ecosystem of libraries.

Let me ask the obvious question.

Why hasn’t the go community, of professional software engineers built an even richer ecosystem of libraries?

Is it ennui, incompetence, or attitude?

As Go came from Google, is that the attitude was, “I am a professional I’ll just write my own code to solve X”, rather than considering building a library that others can use?

Are libraries harder to build in Go? Is adoption of libraries by the Go community different?

Is it a mindset, that libraries are uninteresting?

Or is it something else entirely?

It hasn't been around as long as Python.
That is true, but where are the go libraries for machine learning, tensors, LLMs, equivalents to PyTorch that I see bandied about?

Others have stated that they don’t need such libraries in Go, or that Python just has a glut of libraries that are a sort of detritus obsolete or language version specific.

Why isn’t Go then, THE language of choice for machine learning, analytics, fast prototyping, data conversion, ETL, etc.

What I’ve heard of Rust in comparison is that the syntax of the language & the learning curve is counterintuitive for engagement by non-computer scientists or systems programmers.

Seems expected then that, non comp-sci folks will choose a language that is more accessible, with an ecosystem that lets them get things done in a short period of time.

I would wonder if it it that the experts & heavy users of Go or language architects moving Go forward see any need for a parallel course of engagement to bring Pythonists into the fold or to allow Go to become the language people choose over Python or TypeScript, et al, by providing a best of class approach to quickly prototyping and extending into well architected systems as an underlying function.

Why do people use Microsoft Windows on x86?

The computer industry has a bizarre reputation for moving fast and breaking things. In fact the industry is shockingly conservative. You will encounter many, many programmers who flat-out refuse to learn new things.

Most companies & universities aren’t exposed to cutting edge or even modern technology. They stay in their bubble.

Leaving Silicon Valley, I’ve found the engineering management culture can be averse to training and allowing active skill building via development projects.

Just code that shit in Java or C++, doesn’t matter if you haven’t been trained in SQL properly or are even aware of best practices.

That culture leads to some gruesome product implementations & upgrade scenarios.

Hell, our IT department blocks this very website from being accessed.

I access it from my personal devices.

Compare the number of programmer-hours on Python to Go. Having a ~15 year head start helps a lot.

Plus, I've been programming in Go professionally for a while and it's been a while since I reached for a critical library and it was missing.

Go ends up needing fewer libraries anyhow; in Python you have the pure-Python version, no, wait, the Twisted version (which may not be current but are still all there, increasing the library count), no, wait, the async version, no, wait, the Python 2 version, no, wait, the one that binds to a C library.... and actually this isn't specific to Go, it's really more specific to Python. Library count gets bloated up over the decades by the fact that when, for example, Python went to async, all non-async libraries in which async was relevant suddenly needed a clone. Go has had effectively no language changes which create such parallel libraries (note changes, not additions; Go has had additions which create opportunities for more libraries but don't create lots of parallel libraries). I don't know that Python is uniquely changing, "best practices C++" is arguably up there, Javascript has had a lot of churn, but it's in the higher tier of such things. Languages that don't churn like that should be able to cover the same amount of "need" for libraries in fewer libraries by the numbers.

Not sure if rhetoric question only, but Go has the expressivity of C. Let’s not compare it to python that is often textbook pseudo code like.
If the “expressivity of C was such a wonderful thing why was Go even needed? Why was Java & J2EE promoted to enterprise development?

Might it be that coding in C was and is hard and further that memory management pointer issues and more led to unstable code?

I wrote my comment as a negative — C is terribly inexpressive, just as Go.
What's the Go community? Google employees? There's no Go community, it's a corporate language.

Why hasn't the Visual Basic for Office community produced more libraries?

The author of the post seems like an evangelist for the Go programming language.

> And, not to put too fine a point on it, but if you can code Python but not Go (or another decent programming language), you probably have no business writing software for a living.

What's funny is that (in a different Python rant from another author), it was pointed out that Google was the heaviest pusher of Python in the early 2000s. It probably would have been Java (from Android and elsewhere) had it not been all the legal stuff with Oracle brewing. So, Python here, Python there, Python everywhere... then Google invented Go and Dart and other shiny new toys and began pushing them everywhere.
> It probably would have been Java (from Android and elsewhere) had it not been all the legal stuff with Oracle brewing.

Oracle started buying Sun (and consequently Java) in 2009; the merger was completed in 2010. So I fail to see how that could have influenced Google's purported aversion to Java in the early 2000s, even as late as 2007 or 2008.

Go was written to replace C++ and Java at Google, not Python. But after it launched many Python developers in SRE switched to Go- for good reasons. Initially it was a bit of surprise to the Go creators.

Python (fronting C++ code) still plays a huge role at Google. I don't see that changing. Go has almost zero story for scientific computing.

"there are only two kinds of languages: the ones people complain about and the ones nobody uses".
My experience with Python can be summed up as: it's tempting to start something with it, since it has such low (initial) friction and hey, "this is just a small throwaway project anyway".

Months or years later, it's a beast, hard to understand or refactor, full of holes and pitfalls, and Python's terrible tooling doesn't help either.

And I never learn the lesson!

What tooling are you missing?
I've been down this road before on HN, so let's agree I don't find the existing tooling satisfying at all.

The linter is ok, and an occasional lifesaver (but it shouldn't even be needed! It requires extra work to catch problems that other languages catch "for free"). And it shouldn't be a separate tool. It's also cumbersome to use, silence what is not needed (way too noisy) and fine-tune it. Inline comments to enable/disable it for specific warnings look ugly, too. Python devs tend to suppress whatever bothers them instead of fixing it because it's not in their culture.

The type hinting checking is terrible. It's getting better, but it still misses obvious things and requires too much hand-holding. In my experience, average Python devs don't use it because they don't understand it, or don't find the ROI worthwhile. And because it's optional, they can just pretend it doesn't exist (or complain if you make it mandatory).

The mess that is dependency management has been discussed multiple times. In Python's defense, it's in "good" company with other messes from different languages. But Python's case seems particularly horrifying.

In general, with tooling, Python lives in a special hell where every blog and article will tell you "it's awful because you're doing it wrong, you should instead [use|avoid] pip, pyenv, pipenv, poetry, <my custom script>, <some deprecated tool that nobody else recommends>, <cutting edge tool that is incompatible with everything else>".

I used to love python. It made me productive.

Until it introduced the haphazard type system. Now I need to import types in every file, use IF to guard it in CI in every file, and use a powerful IDE to be able to use the benefits of typing.

typing brings me no happiness either, because it's a lot of work without being complete anyway. Annotations that are not checked vs actual behaviour at runtime can always, by the laws of programming, be subtly incorrect.

I still use python. The recently introduced match statement is a great addition, IMO.

> Now I need

You don't need to do anything, you can ignore all type hints

> use IF to guard it in CI in every file

Are you talking about "if TYPE_CHECKING:"?

Your other option is to put "from __future__ import annotations" at the top of the file, or wait for Python 3.13 when PEP 649 lands and type annotations become lazily evaluated.

Everything is terrible if you use it long enough. Some things are more terrible than others for certain use cases - a thoughtful developer understands the weak points of the tooling, and selects the proper tool for the job at hand.
I wish people could be honest and say they don't care for some language or framework or OS for personal or aesthetic reasons, rather than having to round it up to being objectively bad, but then I suppose nobody probably would click on "I don't like Python and have got some nits to pick".

Oh and he just says what is supposed to be quiet part at the end:

>And, not to put too fine a point on it, but if you can code Python but not Go (or another decent programming language), you probably have no business writing software for a living. I know it sounds harsh and I apologize for that, but writing software is a profession and hence you should have the knowledge, skill, and experience to use professional tools.

Hear that all data scientists, flask devs, systems engineers, and ML folks? Python is bad so you should quit. ;)

Aha, you pointed out the disease.

This is the biggest problem in software and it's kind of intractable.

The ideal world has tools that empower everyone to do what they need to do, which to some extent must include an activity like programming.

But, and this may be unconscious, "people who program for a living" have a strong incentive to gatekeep.

What's amazing is people who program for a living, who people would normally think of as being "experts", have so little knowledge of all the different types of programming that is done by, well, people who program for a living, and the tools they use to do that programming.

Not only then is it gatekeeping, it's also a sign of an inexperienced programmer.

I'll give one thing to Python programmers, they tend to work directly with their end users and build solutions that matter to them. Anyone that's done that kind of work knows it's difficult, regardless of programming language being used.

And arguably, is the more "important" work, or at least the stuff requiring the most attention?

I know that's a tough thing to say -- but yeah, the irony is that a really really good "low-level programmer" is destined for obscurity, because things just work and once they're working people forget about it. Shouts to Linus Torvalds.

You're saying that specialization is bad and that specialists can't be experts.
No. I'm saying people that make these ignorant statements aren't experts.
I see this sort of person as an extremely rigid, unbending, dime a dozen type person even if they’re very intelligent. I’m in this business to succeed and build and create things, there is very much an “energetic” aspect and his energy is dead as fuck. It’s a very simple fact that some see it, and some don’t. He’s one who doesn’t, and all those that see it can see it so clearly. He’s most definitely not someone I would want on my team.

The amount of idiotic … implications of his statement is so excruciating it’s physically painful to me. But I encounter this unadaptive unawareness all the time with working with programmers from other teams, etc so I’m used to it.

He published an article in June titled "It is not cool to be unkind!".

Interesting contradiction.

I know someone like that, very energetic, full of ideas, but so stubborn I'm sure it holds him back.

Lol bragr did not offer any ideas, only cranky complaints. Who cares?
> I wish people could be honest and say they don’t care for some language or framework or OS for personal or aesthetic reasons, rather than having to round it up to being objectively bad, but then I suppose nobody probably would click on “I don’t like Python and have got some nits to pick”.

Yeah, this kind of hyperbolic headline article repeating mostly dead-horse arguments is just low-effort click farming, not a serious contribution to the discussion of anything. All it adds to what is a well-trodden debate is…factual errors, like the claim that Python prominently features “lazy evaluation” (while, as in any language, you can arrange laziness in Python, it is very much eager normally.)

I really think that Python is not a good language for ML, it just got "there" first.

The ecosystem is the real plus, of course. But the language is a headache for this. I agree with the "false economy" angle. I would happily trade the "agility" of dynamic "gluing" with some kind of real type safety, human-readable error messages and performance[0].

[0] - hiding C in Python's clothes doesn't count :)

Python is the de facto glue language with one of the biggest ecosystems out there, that makes it possible to use any kind of over-the-top library that does 1093 things after a single `import antigravity`. Also, ML absolutely makes sense for python, it’s not like most PLs have actual support for video cards — ML is very specifically about manipulating data (a fundamentally dynamic task) and calling out to specific libraries for training, a very glue-task. Give me any language better than python for that.

Quoting Brooks (butchered): “the only significant productivity improvement comes from relying on code that is already written”. Your fancy “better” language has not even 1/10th of what python has, it won’t replace it.

> Python is the de facto glue language with one of the biggest ecosystems out there

I never contested that.

> ML is very specifically about manipulating data (a fundamentally dynamic task)

I disagree strongly with using dynamic languages for data. Data has dimensions, units, types. You need to know that you're not adding coats to horses or USD to EUR. You need to know that you didn't silently sliced by the wrong axis. You may want formal verifications. You may to transform data without worrying about silent errors.

All the "metadata" and wrapper classes ML in Python are just trying to give you what the language can't.

> a very glue-task. Give me any language better than python for that

That's my point exactly. ML has evolved beyond glueing a few C libraries. It needs complex, big programs, which is an area where Python is terrible. Also the different nature of the "glued" components (each with its own data formats, protocols and calling conventions) makes the glue a mish-mash of untyped mixed magic idioms.

Training and using ML is different. It has been relatively common to bundle the trained weights with a different programming language system - but training can be a more exploratory phase, so python is not a bad fit for that.
Clearly a Go enthusiast who never mastered Python. And, really, Go? If your were pushing Rust mayyyybe I could give you the benefit of the doubt.
Every single "This language is good" or "This language is bad" take really needs to always come with a "for what, exactly."

"This wrench is really bad for hammering nails!"

Agreed. But I also think it's fair to criticize general purpose languages on general grounds :)

It's just that this article isn't very good at it.

It's fair, but the other thing happens WAY more.

It honestly just strikes me as very odd how e.g. even "just use multiple languages" is done a whole lot, but not really talked about as a good idea (as much as MY LANGUAGE IS GOOD AND YOURS IS NOT)

The author of this article does highlight the cases where using Python didn't work out well for them, in fact multiple times.
The context the author was working in was a large corporation with a demanding collection of services that needed to be managed. Many of the tools to manage those servers were written in Python, since many people know it, it was already widely used at the org, it had good support for C++ interop (also widely used at the org), and Java was found to be really clunky for sysadmin tooling.

I've seen both sides of it- I worked in the same sub-org as Jos, and my very first job was cleaning up a large pile of incredibly important and variable-quality Python code used to manage a fleet of database servers. the code was tools to do useful things like implement failover of the replication master (across ~90-120 shards) from one region to another for maintainence. Or apply schema changes across all those master shards. Or monitor the shards at runtime.

At times, the code would Exception (literally, crash with a Python exception) during the middle of an important but routine maintainence, and the migration would be half-done. I was hired- literally, this was my job- to add tests to the code until it was much more reliable. Working on that convinced me that rather than type-safety (which is nice, and can be used optionally in python), high test quality and high test coverage of paths used in production were more important to keep the code running smoothly.

I just wish Python hadn't made strings a sequence type, as one of the most common errors at the org was accidentally e m a i l i n g e v e r y s i n g l e letter in a To: string. IE, if it was "To: bore-sre@stoogle.com", then b@, o@, r@, e@, etc, would all get an email saying "Process failed..." And r@ would reply (because he's rob pike) saying "your python program has a bug...."

I’m not a fan of Python, but this article is insufferable in tone. If Python doesn’t meet your needs, don’t use it. There’s plenty of oddities to gripe about in Python, but this article doesn’t attempt to learn something or make a larger point beyond “my favored approach is the only valid approach”. Sorry, but that’s not an opinion worth considering.
As much as I personally dislike python, I completely agree with this, but want to flip it. If pythong meets your needs, absolutely use it. Don't complain about how Visual BASIC doesn't work for you on your way to downloading whatever version of python is current this month.
My problem with python is that it's branded as cross-platform when at the end you are required to learn docker and run on a linux environment to really stop suffering.
How does running a Python 3.4 app in docker help? 3.4 is deprecated and will get no more security patches. Running it in docker doesn't change this.
> And, not to put too fine a point on it, but if you can code Python but not Go (or another decent programming language), you probably have no business writing software for a living.

Come on man. There's being opionated, and then there's this.

Really for all the complaints about JS/NPM/Electron it looks absolutely genius next to Python tooling and PyInstall.

It's extremely frustrating that you're forced into using it to access technology that doesn't even use Python really it's just the composing glue sticking the native C++ or GPGPU code blobs together.

This {{insert_programming_tool_here}} has not worked well for me and the projects I’ve worked on so nobody should use it. And if you do use it you are not a real programmer and you should be ashamed. Because only someone who uses {{isnert_programming_tools_i_like}} can call themselves real programmers. The recipe of these articles.
I have grown to like Python for small programs and scripts because of libraries like TensorFlow, PyTorch, LangChain, etc.

I agree with the author that there are better languages for large applications.

Python is a horrible language, but not for the reasons the author gives. Just because range() returns a generator doesn't mean the whole language is lazy. Several Lisps allow something like duck typing and they're not horrible. It is possible to reason about program behaviour in dynamic languages, but JavaScript certainly makes it hard.

Python is a horrible language because it is not a language. It is a family of languages that changes every October. Sure, 3.x doesn't introduce as many backwards-incompatible changes per version as 2.x did, but that's like saying World War I wasn't horrible because towards the end fewer people seemed to be dying every week.

I've been programming in Python for most of the past 10 years, and I've never experienced a regression in backwards-compatibility between minor releases. What problems have you had?
The syntax of the language changes every version in non-backwards-compatible ways.

If you have a couple scripts, sure, maybe you're not affected. But when you buy a company that shat out 90kloc of python and then all the employees quit, it's not a happy day.

And sure... I shouldn't have used those features. I get it. I'm the one who's bad because I'm calling your baby ugly. Even though I wasn't the one that originally wrote that code.

Though I did write some code that used package variables. And then the syntax for package variables changed, but that was an easy fix. And then the scope of package variables changed to be class variables, which is totally fine, but harder to find. Then the syntax changed again, but in a way that made it harder to fine. And then the debugger stopped working if you enabled async io for a few versions.

Python is for total amateur code fluffers.

Which syntactic features have changed in ways that aren't backwards compatible? I've had some minor headaches, don't get me wrong, but in each case those headaches are a result of interface changes to common objects, like Exception-types. Python has added some syntactic sugar between minor releases, sure, but never at the expense of backwards compatibility.
Package variables. Class variables. Syntax changed between 2.3, 2.5 and 2.7. And the semantics changed somewhere between 2.3 and 2.7.
> because the value of a good programming language is that it will not allow you to write programs that are structurally deficient.

Ummm... okay.

I'm not going to cheerlead for Python here (in fact I do not like it at all and also avoid it whenever possible) but many of this author's points seem to boil down down to "screwdrivers are bad, here's why you should always use hammers instead".

Different tools exist for different purposes.

Python was already the most popular language for carbon-based intelligence, but now it's also becoming the one and only language for silicon-based intelligences.

The future is artificial intelligence programming Python and human programmers writing blog posts about how terrible Python is.