My Switch Away from Python
John Naylor
Posted on November 7, 2021
Table Of Contents
- From Beginner to Professional
- Typing
- GUIs
- Deploying
- Containers
- Extendability
- Typing
- Rust
For some context for this article, python was one of the first languages I learned and became comfortable with. The incredible part about python is how accessible it makes programming to the world in comparison to other beginner languages like java. With that being said, the longer I've been in the software development sphere, the more I've started running into issues with using python in projects that I've outlined a bit here.
From Beginner to Professional
Undeniably, Python has made huge steps in program accessibility for not just the average computer science student, like myself, but to everyone around the world. It's given people the freedom to focus on being creative and not thinking about what's going on behind the scenes. And this accessibility is coming from a real honest-to-god programming languages with batteries included, not some toy language like MIT's scratch or whatever. Machine Learning is probably the biggest example of how much a field can benefit from having an accessible programming language behind it. If ML was still all done with something like C/C++ rather than in python atop numpy/tensorflow/matplotlib then you could make the argument that ML wouldn't have risen to popularity like it has. Looking at how the future is moving, I see two things that are sparking the end for python: the invention of the newer compiled languages (Swift, Golang, Rust) and the movement to NoCode.
Most of my projects I'm either writing something that is going to be fairly large in which case I want to use something that gives me a ton of power and performance (i.e. some compiled language that is easily containerized and not python) or I'm gluing a bunch of pieces together to make something using existing tools in which case I'm using NoCode stuff (Zapier, Airtable, IFTTT, etc.). With NoCode becoming so popular, the barrier to entry is almost nothing. Look, for example, at the apple shortcut app for iOS, I've seen just about everyone with an iPhone make something tiny with it and that's the essence of programming really. This space that python filled is being taken over by these tools and maybe they have a way to write extensions in python but let's be honest with ourselves, most people write the extensions in javascript (unfortunately 🤢). It'll be a bit till this way of programming has enough modules/libraries and support to take over Python's foothold in the accessibility space but it'll definitely continue to be a major reason to switch away from python when you just need something simple and rapidly developed.
Typing
Going along with the theme of accessibility, Python has been able to attact a wider audience by going with a dynamic typing system vs the tradition static typing of langauges like C or Java. This is great so beginners as I mentioned because of how forgiving it is and how easy it is to glue things together in code. For a big project stand point, dynamic typing is a huge pain in the ass: "Why am I getting this random type error in my code nowhere near where the actual value is being assigned!?" or "What the hell does this person's library take in as an input!?". This sucks, luckily, a lot of projects and libraries made for big projects use Mypy, Python's static extenal type checker, and proper type annotation (well at least I hope the big libraries have proper type annotations). And Personally, Python's type annotions along with Mypy is much better than typescript is for javascript. Although, just like how typescript isn't a complete fix for how terrible javascript is, so it Mypy for Python. I've seen too many people not use type annotations for things and if their aren't type stubs, which I've found for a lot of data science stuff, then it's really not that helpful. There are other options for types like for example the really incredible library Cython. Cython compiles python code into C, allowing you to add type annotations to your python that'll actually speed up your code. The major pain in the ass with this though is that Cython type annotations aren't the same as the normal Mypy type annotions and Cython types match directly to C types whereas Mypy type annotations do not.
Mypy
def f(x: int): int:
y: int = 5
return x + y
Cython
def int f(int x):
cdef int y = 5
return x + y
So it's kind of a mess to look at and deal with. Going forward, it really seems that Mypy type annotations are really cool but they'll never replace a really good statically typed language. Many of the new modern languages that I mentioned earlier like Swift, Go, and Rust are all statically typed, but the compiler is smart enough to infer the types of variables.
let x = 42 // x is inferred to be an Int
This is super accessible and the static type system doesn't get in the way unless you try and do something stupid.
GUIs
To be honest, there isn't a whole lot to say about GUIs in Python and that's the problem. My personal favorite GUI framework for Python is PyQt but it's really just a wrapper around the C++ Qt library and it shows. For a language that's so friendly to beginners, a really solid GUI framework should be essential. The undisputed leader of GUIs is javascript whether it be on the web or as an Electron desktop app. Compared to a quick Electron app, PyQt apps provide a less than optimal developer experience. From the mobile side of things the normal Swift for iOS, Kotlin for android, and javascript/dart for web apps dominate the field. Quick cross-platform GUI apps would be great to have but unfortunately Python just isn't there.
Client Side Deployment
Even if there was a good framework, it would have to address deployment. I recently tried deploying a PyQt app to some windows machines and it sucked. My team even tried compiling to an exe and that was a whole ass experience. Client side deployment for interpreted languages seems to always have a few issues and it seems to be especially prevalent with python. The operating system provided python interpreter always seems to cause problems without fail and particularly with beginners who aren't used/don't know who to set up a virtual environment for python. Going along with that, I've always found python dependencies to also be a huge mess when working with/deploying python code with setup.py
being not very robust to errors and difficult to understand for beginners compared to other languages (rust's cargo being one in particular that I like). Fortunately, there are a few projects in the community that make dependency management easier like pipenv
and poetry
. Both tools make things pretty straight forward since pipenv
feels like node's npm
while poetry
feels like rust's cargo
.
Server Side Deployment
Back in dinosaur times, languages like C were running into an issue: they weren't as cross platform as the industry needed them to be. Through that, the magical thing known as the virtual machine was born. Java with it's huge, fancy virtual machine could sweep the market because it didn't care what architecture it was on as long as it had a java virtual machine. As the market expanded, interpreters and virtual machine were doing great except for one problem: dependencies. Java apps won't run if the machine they're running on is missing a dependency. Likewise, python apps will crash if the machine is missing a library. The answer to this and all the worlds problems were containers.
Luckily, server side, containers make deployment and dependency management easy even for the most difficult languages. With docker I can do the beautiful thing and pull in an image with a python interpreter that I can wrap everything in. I can't be too nice because even with containers, python seems to do worse than most other languages. Interpreted languages are known for having bloated container sizes (just the base python image is ~1Gb), which is a core reason that new compiled languages like Go can get away with not having an interpreter. Python, being such a high level language, has lots of important libraries that are actually just C code under the hood and when that gets factored into container builds it can lead to slow build and start up times. That's not just a python problem though, the JVM which used to be this really amazing thing now just created bloated containers with extremely slow start up times.
Rust
This final section is mostly just my opinion alone. I haven't researched much about what other people think of this matter but personally I strongly think that python should distance itself from C/C++. The main interpreter for python, CPython, is unsurprisingly written in C. This is great for speed but it means that contributing to the language is becoming more and more isolated from the majority of users. C (God's programming langauge) itself just is incredibly unsafe and should definitely not be used in any kind of production environment. Of course nobody is really arguing that C is unsafe which is why plenty of companies and organizations have moved to rust. Rust is the modern choice for things that need to be ultra efficient but also safe for production. Python is used globally in production environments and run by an unsafe interpreter. I think python should seriously be considered for a rust rewrite. The creator of nodejs is already attempting to do this with server side javascript by starting the project Deno. Deno is a safer version of nodejs written in rust. There are already community attempts to move python to rust just as the open source interpreter RustPython. One of the beauty of the python interpreter (especially compared to the JVM and V8 for node) is its amazing simplicity. People should be able understand the interpreter their code runs on and rust, being able to abstract things away from the bare metal while not sacrificing speed, would be a major step for this.
Of course a total rewrite of a code base like this is insanely hard and would be a lot of work but it would also have the unfortunate effect of breaking anything that relies on CPython's C API. CPython can't get rid of the Global Interpreter Lock (GIL) because it would require breaking some of the C API. A rust rewrite would do that times a thousand. The time and energy it would take to rewrite all the libraries that rely on the C API components of python could end up killing the language entirely. People may just end up deciding that it's not work the effort and more to a different programing language. It seems that with the addition of Tensorflow for swift and Python Interoperability in swift, the data science and machine learning community, where I think a majority of the C backed libraries come from, might move over to swift regardless.
Conclusion
Until something major happens, I don't see python going away that easily. My guess is that as time goes on, people will have less and less a need for it. It'll still likely be one of my go to languages for quick prototypes (there's nothing like spinning up a quick flask server for a hackathon). Plus as things stand now, everyone knows or has seen python before so demonstrations in it are safe. But when it comes down to making projects that I plan on keeping for more than a week, I now look at other choices for my language of choice.
Posted on November 7, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.