Why not Python?
Python. It very well could be the most used programming language out there. It’s easy to see why:
- It’s beginner friendly
- It has a vast amount of libraries
- It’s named after Monty Python
- Other people use it
I’ve bolded that last item because it’s likely the real reason that Python is popular. That might seem like a Yogi-ism, but it’s true.
The wrong tool for the job
Python is used most widely in data, analytics, and machine learning, with a lot of the work including image manipulation and data visualizations. All of these tasks deal with massive data sets and file sizes, meaning the code is crunching numbers all day, all night. So, Python, as a language, should be mad fast and efficient and secure, right? Right!
It should be, but most definitely isn’t.
🐍 == 🐌
Here’s the rub. Python is the worst choice for doing what it does. Of note, Python is
- One of the slowest programming languages out there
- Insanely memory intensive and power hungry
- Vulnerable to attack
- Susceptible to random runtime errors
Each one of these issues, by itself, is reason enough to look for a different paradigm. Put another way, Python is sluggish, selfish, poor at its job, and let’s the bad guys in.
Too little too late
The thing is, the Python community kind of knows these shortcomings. Kind of. In 2020, none other than Microsoft lured the creator of Python, Guido van Rossum, out of retirement to head up a team to revamp the language with the goal of making it twice as fast, or still 5-50x slower than C, C++, or Rust 🤦. That’s pretty pathetic.
The 3.11 release of Python gained 25% over 3.10. Whelp. That took a team at Microsoft years to accomplish. There are already much better choices out there that are safe as safe can be and run on bare metal blazingly fast. Plus, these competitors adhere to zero-cost abstractions and backwards compatibility, which we’ll get to in a minute. The war is already over, guys.
What’s more, Guido previously worked at Dropbox and was tasked to “wrangle four million lines of Python code.” Python is supposed to be cool because it’s Zen. It even has a poem you can import called The Zen of Python:
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
But it’s also possible that being one of the only kids on the block to ditch braces actually leads to difficulty programming in other languages or creates confusion. Being “Pythonic” is awesome, until it’s not. At times it’s childish.
>>> from __future__ import braces
SyntaxError: not a chance
And other times being Pythonic also borders on being moronic. Martin Fowler knows:
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
The problem is that Python code tends to be less extensible than other code. So not only is it slow to run on machines, it’s slow in the hands of humans, too, which is very costly. Take this example from Dropbox:
When the company grew, new engineers could not understand the clever but ‘short and cryptic’ code written by and for earlier developers.
And, for being so Zen, Python sure botched the transition from version 2 to 3. Like, majorly. Dropbox, which had Guido himself to guide the process, took over 3 years to migrate from 2 to 3, and wasn’t done by the time he retired. Moreover, the Dropbox team basically said, “F this,” and switched their sync engine to Rust with amazing gains across the board, calling it a “force multiplier for our team, and betting on Rust was one of the best decisions we made.” Ouch.
Here’s an account of a developer’s experience in migrating over from Python 2 to 3. Let this sink in:
When I prepared for my migration, I read a lot about Python 3. I was surprised to find that it has been in development since 2005! The first release was way back in 2008. Ever since then the Python community has been pushing for developers to make the jump. However, after an unsuccessful deadline in 2016, the community decided to do a hard stop in 2020.
It took over a decade with breaking changes to sever ties to Python 2, and yet, somehow, many people and companies are still using Python 2 despite its vulnerabilities.
Allegory of the battle of the bears
For data manipulation, the go-to option is pandas. It’s been the choice for some time, but recently a new bear arrived on the scene: Polars. Polars is written in Rust, so it all but takes care of every single shortcoming that Python, and by way of extension, pandas has. It’s not a fair fight, really.
Read more about the breakdown here, here, here and here, but this is the key takeaway:
While Pandas can take minutes of time to simply sort the data frame, complex sorting functions can be evaluated in not more than 15 seconds in polars.
Here’s what it looks like in graph form:
Add in that pandas, much like the Python team of yesteryear, is repeating the mistake of not taking backwards compatibility seriously. Big bummer.
Long time pandas user but changes like this are why polars is becoming more popular i guess
Maybe Mojo 🔥
The most promising recent development is Mojo. Chris Lattner, who also spearheaded Swift, has been influenced by Rust and &borrowed—get it??—heavily from the 🦀🦀 to gift the world with Mojo. Some benchmarks show that Mojo is 35,000x faster than Python, and, as a superset of Python, you don’t have to worry too much about throwing away your old code, doing a whole rewrite, or training a team the ins and outs of Rust. It’s still extremely new and untested—like, it doesn’t even have classes yet—but it sure seems like this is where people should be focusing moving forward.
The Mojo language has lofty goals: we want full compatibility with the Python ecosystem, we want predictable low-level performance and low-level control, and we need the ability to deploy subsets of code to accelerators. Additionally, we don’t want to create a fragmented software ecosystem—we don’t want Python users who adopt Mojo to draw comparisons to the painful migration from Python 2 to 3. These are no small goals!
Stay tuned. It’d be great, too, if this team also solved Python’s package management issues. One can dream.
Sayonara, snake
So why deal with all this hassle? Well, don’t. The path forward is pretty clear. For decades Python has risen in popularity, and despite this, the changes to the language and its ecosystem of libraries show that improvements are still wanting in major ways, and what improvements there are come with heavy costs.
The world of machine learning, IOT, and AGI is not far off, and that world will only require more timeliness, more safety and security, and more efficient use of resources. These are things that Python cannot and will not deliver. Python is great for hobbyists and kids who are just getting into programming via RaspberryPi, but it should not be the language of choice as we are steadily handing over the reigns to computers.