A Pythonista's irresistible attraction to Rust



I've been an enthusiastic Python developer for more than 10 years now and I now find myself irresistibly drawn to Rust. I'm of the opinion that Rust is especially attractive to a non-trivial subset of Python developers and I'd like to tell you about it.

Technical merits

In this article, I talk about feelings rather than technical merits of Rust vs Python. Armin Ronacher has made technical comparisons better than I could and I encourage you to read them:

Attraction to Python

To understand my attraction to Rust, one must understand why I was attracted to Python in the first place: elegance and expressiveness.

When I began programming in Python, I had a Delphi background, which was a pretty good language for its time. I had nothing to complain about Delphi because I didn't know anything better. But then, as I dabbled in Python, something happened.

A weight was lifted from my shoulders and it felt awesome.

I realized that until then, I had been wasting so much time in tedious and repetitive memory management tasks. Suddenly, things that I had learn to dread, such as returning a list and figure out when I was going to free it became trivial!

Thanks to Python's expressiveness, I became much, much more productive and I loved it. This expressiveness and elegance enabled me to develop a sense of code aesthetics and I was hooked. Drawbacks didn't matter, this was too fascinating so I jumped ship.

Attraction to Rust

When I first heard about Rust, a year or so before 1.0, I was immediately intrigued because it could replace C, of which I was afraid for the exact same reasons as Dan Callahan at PyCon 2015: fear of making memory management mistakes (which can have dreadful consequences). At first, I was interested in a C replacement to make Python extensions. But then, after 1.0 was released, I played with Rust more seriously and something happened.

A weight was lifted from my shoulders and it felt awesome.

Suddenly, nearly all of the program's control flow was validated at compile time (unless explicitly ignored with unwrap() calls)! Let this sink in for a second... Null pointer errors? Gone! Unhandled errors? Gone! Wrong variable type? Gone! I saw whole classes of bugs evaporate before my eyes (and in an elegant manner too! I really like how Option and Result work) and I was excited.

Until a few years ago, I was working all alone in my own code and the cost of such bugs weren't very high. The fixes usually took a few minutes and could be included in the next release of the app. No big deal, expressiveness gains more than made up for it.

Now that I do consulting work, both the cost and the frequency of this type of bugs have increased significantly. The cost because in my firm, each bug has to go through a process that is much more time consuming (and boring!) than the bug fixing itself (for "quick and easy" fixes I mean). The frequency because I no longer work alone and it's much easier to make the "type/null/error" types of mistakes when you're not in your own code than otherwise.

In other words, I came looking for a safe C and I found a language that I see myself programming in all the time.

Sure, there's a price to pay. The language is less expressive than Python and some tasks that are trivial in Python are significantly more complex to achieve in Rust because of the lack of GC. But it's been what, 4 months since 1.0? I've been playing pretty intensely with Rust and I have yet to see my entusiasm fade, so I'm guessing that it's worth the price.

What about Go, Nim?

Why am I so excited about Rust, but not Go or Nim? As they say in the song, I played with memory management and I liked it. Until now, the only way to play with memory management was to step into "unsafe land". With Rust, it's not the case anymore. It's actually really fun to deal with memory ownership constraints.

Besides, now that I have Option and Result, I don't want to give it away. Nim has not nil, but it gets things backwards. If the default is to allow nil, then lazy developers are going to allow it, then forget about it, then access it when nil. That is, unless the Nim compiler analyzes the code to ensure that every access to every nullable variable is inside a if x != nil block, but I'd be surprised if it did. (Update: Apparently, this is under discussion)

Also, I've always felt drawn to systems/embedded programming, but not enough to want to play with the metaphorical matches of memory safety. With Rust, I feel closer than ever from that field and it's exciting. Go/Nim makes my playground more efficient, Rust opens a new one.

I think that a non-trivial subset of Python developers feel the way I do. They've been excluding themselves out of a whole programming playground, and suddenly, the doors are open and we are given helmets and kneepads. Whoohoo, let's play!

But for now, I do web development for a living, will I do my next website in Rust? I hope I won't fall this far in wonderland, it seems like hubris to me. But now that my Python enthusiasm is waning, I might actually look towards Go and Nim for that... until I take myself out of the webdev field to get back to my newfound playground :)