These days I turn to recreational programming more often than usual. Solving fun problems makes me feel less confused and helpless about the pandemic. It’s a coping mechanism and a good one at that.
One thing has been an especially surprising source of joy for me: Rust. Surprising because I’ve been known to have an on-off relationship with the programming language since its 1.0 release. I quit Rust more than once – both professionally and personally – mainly out of frustration with a subpar development experience and general lack of libraries.
Looking back, I’m thrilled that I gave Rust another chance this year.
That was then
Back in 2017, I wrote that “Rust lets you control almost everything, but as a beginner, it’s also hard to compile anything. As a result, Rust continues to make me look bad.” I was disappointed. Again.
At the time, I was working for a chaos engineering startup that chose Rust for simulating common server problems such as high CPU load, increased network latency, or random application crashes. A reasonable choice if your goal is to inject low-level faults in a predictable way, right? After all, Rust is said to be our best chance at safe systems programming. That may very well be true.
However, back then, I didn’t think Rust was the best option for the client side of the product. The main reason was productivity – or rather the lack thereof.
In 2017, my day-to-day Rust experience boiled down to the following:
- Writing code in Vim with bare-bones syntax highlighting
- No code completion and no “go to definition” (the Rust Language Server was still in its infancy)
- Effectively no code formatting, since
rustfmtjust gave up whenever a line was too long (seriously)
- Docs were hard to find or non-existent
- The same goes for high-quality code examples
- No official Rust Docker images, homegrown CI pipelines only
- Compile times were noticeably slow, resulting in long feedback loops
- Speaking of feedback, Rust’s borrow checker made it difficult to understand why it rejected a piece of code and how to fix it
All these drawbacks add up, but what really bothered me was the immature crate ecosystem. To give you one example, when we implemented the ability to inject faults into containers, we couldn’t find any usable Rust client library to talk to the Docker API, let alone Kubernetes. As a result, we were forced to reinvent the wheel several times (and sometimes ended up with a flat tire, in typical startup fashion).
In the face of these obstacles and despite my appreciation for its language design, I often found it challenging to get real work done with Rust.
At least, that was then.
This is now
Today, three years later, I’m happy to report that Rust has changed a lot, and for the better! That became apparent to me when I recently had some extra time between freelance contracts and decided to port a crypto library from C to Rust (because that’s what I do to get out of the cloud consulting bubble once in a while).
I realized that the release of the 2018 edition is particularly noteworthy. It made the language much more productive in several ways: simpler syntax, a smarter borrow-checker, an improved module system, enhanced tooling (both
rustfmt and Clippy, Rust’s linter, hitting 1.0), and a host of other features. Add to that IDE support, incremental compilation, excellent documentation, and immensely helpful error messages, and what you now get is nothing short of remarkable.
Thanks to Rust’s soaring popularity – it has been Stack Overflow’s most loved language for four years in a row – finding a particular crate or tool has become easier (though still not necessarily easy). There are more and more open source projects to explore. There’s a growing list of third-party cargo subcommands (cargo-geiger and cargo-asm being two of my favorites). There’s even a decent REPL. CI/CD is a breeze, and so is cross compilation to dozens of platforms. In short, there’s a lot to love here.
Given these advances, it’s no wonder that learning Rust is also quite different now. The tonari blog captured it well:
A year after switching over to Rust, we onboarded our fourth engineer to the team, who didn’t have much prior experience in either Rust or systems engineering. While the learning curve is undeniable (borrow checker, my old friend), we’ve found that Rust is incredibly empowering for those new to lower-level programming.
Empowering is the perfect word to describe Rust in 2020. What used to be a rough adventure with many pitfalls has turned into something beautiful, something that can lift your spirit. At least, that’s what it did for me.
I encourage you to immerse yourself in a little Rust project today. You might be in for a pleasant surprise.
Update: Reddit thread