Still in love with Rust
I think I've discovered Rust somewhere around the year 2012. Back then it was much different language than it is today. It had green-threads,
~ were used a lot, and there was even a GC.
Rust caught my attention because I was looking for a language for myself. I always considered myself “a C guy”: a bottom-up developer, that first learned machine code, then learned higher level programming. And while C was my language of choice, I couldn't stand it anymore.
I was tired of how difficult it was to write a correct, robust software in C, especially:
- inability to create solid abstractions and nice APIs,
- segfaults, double checking my pointers and general lack of trust in my code,
make-likes building system.
I loved the simplicity and minimalism, I loved the flexibility and control, but I couldn't stand primitivism and lack of modern features.
With time I grew more and more fond of Rust. The language kept evolving in a direction that was my personal sweet spot: a modern C. And at some point I realized I'm in love with Rust. And I still am today, after a couple of years of using it.
Just look at my github profile. It has “Rust” written all over it. And check how my contributions grew since 2013. Rust made me much more productive and enthusiastic about programming.
So let me tell you why is Rust my darling programming language.
Rust gives me confidence. I can still have logical problems or wrong architecture, but the whole classes of issues that I had to be careful about is gone.
No race conditions, leaking resources, dangling pointers, unhandled exceptions, ..., the list goes on.
Rust enables and encourages building beautiful APIs that are impossible to misuse. That makes using 3rd party code, or even your own one code, much easier.
With Rust I can focus on the real problems. It's very important in the age of constant distractions, and one of the main reasons for the overall high productivity of Rust.
One thing that I love about Rust, is that it's reasonably good at pretty much everything. You can write an embedded system in Rust, you can write a WebAssembly frontend code. You write a quick and dirty utility and evolve it into a sophisticated tool. You can write a 3d engine or a game, or a business server-side app, or a mobile app...
No matter what you throw at Rust, it can deliver. Even in places where Rust still falls a bit short, there are no fundamental reasons for it. It's typically just immaturity of the ecosystem and libraries.
The reason is – with Rust combines strengths of typical “best tools for the given job”, without their weaknesses:
- the performance, power, and control of C/C++ (without the unsafety and usability issues),
- memory safety of JVM/scripting languages (without a heavy runtime),
- expressive type system like Ocaml/Haskell/Scala,
- automatic memory management like a GC (without the problems associated with an actual GC runtime),
- dependency management and code sharing like Node,
- error messages like Elm,
- built-in message passing like Go,
and so on...
Being proficient Rust user, I feel I have a very universal tool at my disposal. It might not always be the best tool for the job, but it's going to be at least a decent one. And I can make up the difference by my proficiency, code-reuse between projects, and avoiding the pain-points.
While I was aware of and using C++'s RAII for years, only after using Rust, everything clicked and my mental model transcended my existing habits.
Everything is a resource! Everything has an owner. Everything is born, lives and eventually gets destroyed.
Rust forced me to write my code in a data-centric way and structure my projects in a tree of ownership relations. It forced me to abandon OOP habits. And it turned out that it made my code better: shorter, faster, easier to understand and change.
Now I see how before Rust I was often writing my code in a typical OOP-way: forming complicated graphs, with many objects referencing each other, with unclear relationships. The class APIs, inheritance hierarchies, were there, but they were just obstructing the core problem: structuring and manipulating data.
It would take me much longer to fully elaborate on it, so I will leave it with a quote:
Bad programmers worry about the code. Good programmers worry about data structures and their relationships.
Rust will force you to be a good programmer, you like it or not.
Community and collaboration
Rust community is just the best. Before I started working with Rust, I never really felt like a part of any community. After a couple of years, I feel like a part of a happy family of Rustaceans.
Other than how the community is being run, Rust itself and tools that come with it is making collaboration much easier. Eg. Cargo makes publishing and re-using code so easy and fun!
The fact that language comes with a strong sense of idioms, style and set of tools helping meet the community guidelines (like
rustfmt). makes diving into the other-people projects so much easier. Unlike eg. C++, where everyone is using their own subset of the language, style guides, etc. working with Rust, projects always feel natural and more homy.
The strong type system, safety guarantees and ability to build great APIs, makes it much more innocuous to just merge PRs. During the review, one doesn't have to worry if the contributor is not introducing some catastrophic bugs with every single line.
This might not apply to other people, but for me, being a heavy Vim and command line user, Rust coding experience is unmatched with any other programming language.
rustfmt-provided autoformatting on every save made me not worry about code style at all. I just
:w sometimes, and my code looks always perfect.
racer provided completion make jumping back and forth between code fluid and painless, and plugins like
neomake make fixing compilation errors almost effortless.
And it just keeps getting better
Rust just keeps evolving and becomes better and better every release.
Rust 2018 edition is making Rust even more pleasant to work with.
I'm especially looking forward to
await which will make writing asynchronous code so much more efficient.
The point is... with Rust there's always something to feel good about, and more to look forward to. One thing that I've learned about life and people, is that it's the improvements that make us happy, and after a while, we get used to what we have already and stop noticing it. Happiness is a continuous improvement.
The not so greats...
It wouldn't be fair not to go through the bad parts. After all, love requires accepting the imperfections.
The biggest practical issue with Rust, in my opinion, are compilation times. At some poing, they just become noticeable and can't be simply ignored. They're not terrible, especially given incremental compilation, RLS,
cargo check and other couping methods, but the problem definitely exists.
My advice: if you work with Rust, just get a desktop, with decent specs. and the sheer performance improvement will make the problem disappear, at least for small to mid-size projects.
Barriers to entry
Let's face it – typically developers are familiar with OOP, garbage collected, dynamic programming languages.
Learning something new is difficult and time-consuming, and Rust throws a lot of stuff at the user upfront. Not only you're learning a new language (which is difficult on its own): there's a static type system to get used to, you might need to know the difference between stack and heap, learn about lifetimes, generics,
Options, unlearn some OOP habits and so on...
It's worth it, it pays off, it's not a problem after you get familiar with everything, but it's just a lot of stuff, paid upfront in cash, no refunds. It's not an easy sell.
Because of this, it's always going to be harder to introduce Rust to your peers, team, company and just start the “Rust-project at
$dayjob” ball rolling.
Not every problem has an off the shelf Rust library waiting for you. Some do, but many don't. And in many areas both language and libraries are evolving rapidly. It takes some effort to keep up with the ecosystem and/or implement your own solutions when the existing ones are lacking.