It's almost three months to the date since I've started using Rust at work. In the second week of May, one of our most important partners/providers went under. Suddenly, several activities that used to be automated through this partner didn't work anymore, and we had to find other ways to get things done. At the time I thought that we'd sort everything out in a month at most, so I used Rust to develop a suite of tools to get whatever we needed done. This included:
- Generating CSV files from data in our platform to;
- Import CSV files from new third parties;
- Extract as much data as we could from the soon-to-be-dead provider;
- Reports, reports, reports;
From this description, Rust sounds like the wrong choice. This kind of throaway work is usually the domain of shell scripts and interpreted languages like Python. I had been wanting to have some real experience with Rust, though, so I picked it — I won't pretend my decision had any factor other than "I want to try my hand at this". Three months down the road and with the closing of this chapter still not in the horizon, I'm glad I did it. Here are a few notes about this experience.
Rust is Productive
I didn't come into this from zero. I had read several books, and had professional training with Tim McNamara, the author of Rust in Action, but before this I didn't have any real, practical experience with Rust. I think I was somewhat slower than what I could be if I used a more familiar language in the first 3 or 4 days, and after that, things were just breezy — I had enough in place that my time was spent thinking about the solution to each problem, not dealing with language friction or writing boilerplate. The idea that you'll spend all your time fighting the compiler in Rust is a myth. More importantly, the idea that the time you spend with compiler diagnostics and fixing them is wasted is a lie; the compiler is there to help you, to make sure your program is sound and you don't end up doing something stupid. Fixing more issues upfront means I spend less time fixing them later.
Rust tooling is incredible. Between Rustup and Cargo, setting up a Rust project and managing it is dead easy. Java and Python have nothing over Rust in this area.
Despite its relative youth, the ecosystem for Rust libraries (crates) is vibrant. There's a crate out there for pretty much everything. It might not be as mature as in longer-established languages, but it's definitely enough to let you focus on your core business. Here I think it's worth mentioning the Rust ecosystem tendency to keep things small and modular. Most creates solve one problem without bringing a thousand dependencies in and forcing you to write your program in this or that way.
Rust is Fast
This is not news, I know. I didn't pick Rust for its performance characteristics, but having all my tools packaged as a web service running in a container with a 32 MiB memory limit and executing millions of requests was so, so refreshing. This speed isn't only due to Rust having no runtime and compiling to native code. A lot of its performance benefits come from its underlying philosophy of zero-cost abstractions, an ecosystem that cares for performance, and that together guide you to design solutions that don't waste memory or cycles. Keep in mind that I'm not talking about optimized code here; I spent a total of zero seconds thinking about performance optimizations, and instead focused on solving my problems in a way that felt natural to my domain and idiomatic to Rust, and the end result was unmatched by anything we had at this company before.
The Bad: Async Rust is Rough
Now for a bit of bad news. Async Rust is clumsy. Sometimes it feels almost like a different dialect, with arcane rules for lifetimes and how to compose your code. It's getting better — a lot better — but its ergonomics don't do justice to the rest of the language. In a well-known blog post, Matthias Endler says
Inside Rust, there is a smaller, simpler language that is waiting to get out. It is this language that most Rust code should be written in.
And he's right, but in the current state of affairs it's almost impossible to avoid async code. All web frameworks are built on async code, as is the most common HTTP client, and the most popular SQL library. That's for a good reason; things like HTTP servers and clients and talking to databases are exactly where async can significantly outperform synchronous code, but that comes at a high price.
Conclusion
In the end, I'm very happy that I picked Rust for this project. Would I start using Rust for regular projects? Most likely yes. This is a complex question that goes way beyond the language itsel, but through this experience I've learned that a lot of cons of Rust people write about are not necessarily true, or at least are not a deal breaker. Rust pros, on the other hand, are incredible, and I have the feeling that Rust could be a competitive advantage for a company, if done right.