We all want to build reliable software that makes users happy and keeps our heads free from late-night production crashes on Fridays. But every engineer already knows some stack that can handle the users' needs while tests can check the correctness, so why would anyone bother learning Rust? You might have already heard that it's a relatively complicated language requiring considerable onboarding time. For me and many other devs, it wasn't love at first sight. Memory safety didn't sound like something I missed in my projects and Rust looks kinda boring in many other aspects.

I've been programming for about 13 years in about a dozen different languages. For the past three years, I've been learning and working with Rust among other languages, and now I believe it stands out above all the other general-purpose langs I've encountered.

I don't think that it is a panacea, though. For example, if I need to create a casual blog, I can just pick up WordPress and be done in 15 mins; when I need some heavily interactive web UI, I just take React with whatever libs I might find for the task at hand; when I'm experimenting with machine learning models, I'm always reaching for PyTorch. But, when I need to build something non-trivial, where reliability and performance are real concerns, or the whole architecture is quite complex, Rust is my go-to choice.

Rust's background

Many languages like C++ allow you to squeeze every bit and cycle from the available hardware, but this freedom also leaves a lot of room for potential bugs and security holes. Other languages like Java do the opposite and focus on runtime checks and memory management to provide reliability, but they sacrifice performance and consume significantly more resources.

Some projects like Zig, GraalVM, Mojo, and AssemblyScript try to add the missing pieces for the existing languages to compensate to some extent but achieve only partial success because of the abundance of legacy code. Such code was written with different runtime/compiler assumptions in mind and in some cases is incompatible with growing expectations and requirements. Rust was designed from scratch to provide both performance and correctness at the same time. And because it was a completely new language, its creators weren't constrained by legacy support and were able to combine the best features from many languages into something convenient and familiar.

It started as a personal research project at Mozilla around 2006 because internet safety was their major concern. And since the web assumes execution of potentially unsafe code, it is important to minimize memory-error exploits. Rust reached its first stable release in 2015, so it's pretty young by programming language standards. But, it has already outgrown lots of more mature languages, is the most loved and wanted one according to Stack Overflow surveys for many years in a row, and is the fastest growing according to the PYPL index.

It's important to note here that Rust maintainers weren't delusional to think that devs will just rewrite whole projects in Rust, so they made sure that interop with C, JS, Python, and other languages is painless. Also, they didn't try to make some shiny unique, opinionated thing. Still, they accumulated common patterns and best practices from many languages in a way that feels familiar and intuitive to the broadest public. The result is a modern PL with extreme performance, reliability, and compatibility.

Rust's internals

The core feature of Rust is the deeply integrated borrow checker - memory usage verification system that makes sure that you are never accessing a variable that has already been recycled, not mutating a value concurrently from different threads without the proper checks, not trying to access a collection member outside of its contents and overall makes many types of memory bugs and vulnerabilities impossible to compile.

It often seems like a hostile party breaker when you're just getting started, but it's actually a great friend once you get to know this guy closer. To be precise, it doesn't completely block you from writing dangerous code, but in most cases, it forces you to be explicit about such things and makes manual inspection of the unsafe pieces much easier. This also allows you to be much more confident in 3rd party dependencies just because they compile successfully.

Rust is most often compared to C because it provides the ability to control the hardware on the lowest levels, but I don't think that such an analogy fairly appreciates all the effort that the compiler makes to hide that complexity by inferring types and lifetimes automatically. It's still more verbose than most other typed languages and especially duck-typed ones, but this verbosity mostly comes from the error handling, null safety, and type casting best practices.

Ideologically it's neither object-oriented nor functional, but has primitives from both worlds and allows any approach without enforcing one or the other. If anything, I think Rust is a correctness-oriented language, which might be problematic for pet project prototyping, but extremely valuable for mission-critical services. Worth noting that Rust isn't the first language focused on reliability: there is Haskell, OCaml, and others, but they are pretty exotic for most developers and have their own quirks. Also, Rust is very nice for multithreaded and concurrent programming thanks to borrow checker which prevents races.

Another primary focus of Rust is on zero-cost abstractions - types that don't actually allocate any memory when the code is compiled and running. Mostly they are used as markers for other types which instruct the compiler how these types should be treated. Their purpose is to provide safe interfaces over highly optimized but potentially dangerous practices without adding runtime overhead.

Official Rust distribution packs the compiler, a standard cross-platform library, straightforward package management, an extensible build system, built-in tooling for tests and benchmarks, comprehensive documentation, and even several books for starters and advanced users. This combination and the developer experience with this tooling easily beat every other language known to me.

Build tools and std are available for a very wide range of target platforms, including lots of exotic ones like Fuchsia and watchOS, but I think one of them deserves very special attention.

here comes the WebAssembly

While initially created as a companion for JS to run heavy workloads in the browsers, WASM became a lot more than that. It's supposed to run on the client side with low-level control of the hardware, so it requires significant security measures and was created with almost air-gapped sandboxing in mind. Thanks to the minimalistic security-first design WASM stands out among another assembly, bytecode, and binary formats as an extremely safe cross-platform compilation target. And I want to highlight it because rust's ecosystem has great support for it.

Due to its history and low-level rambling, it was hard for me to grasp the potential that it has initially. But now it's hard for me to imagine a context where it can't be beneficial. For example, the founder of Docker believes that there wouldn't even have been a need for Docker if WASM and WASI (WebAssembly System Interface) existed at the time. And unlike usual Linux-based Docker images, WASM containers can be a lot smaller, consume significantly less resources, cold start a lot faster, provide even harder sandboxing, and have smaller potential attack surface.

It can also serve as a lighter-weight replacement for Java bytecode in many cases, with much broader language support and no vendor lock-in. It enables User Defined Functions written in any language for the databases. It allows you to safely run untrusted binaries. The potential here is just mind-blowing to me.

WASM runtimes can be even smaller than 100kb, and many languages support compilation into WASM to some extent. With this combination of features, you can go as far as cross-platform embedded development in pretty much any language!

so what

Quite likely that by this point you might consider Rust as something cool on its own, especially if compiled into WASM, but real-world development doesn't happen in a vacuum - we need an ecosystem of libraries and frameworks to be able to provide solutions in meaningful time spans. That's something I didn't actually expect from Rust when I was getting started because most young languages suffer from this problem and often quietly die out without accumulating enough packages to become actually useful.

However, that's where safety, reliability, maintainability, and performance played a critical role. This combination of features proved to be extremely valuable for the big tech, so they invest heavily in the Rust ecosystem. It's hard to overestimate how big of a deal this is and the only language with similar impact that comes to mind is Java. But even that isn't the whole story - enthusiasts with all kinds of experiences are learning Rust as their first language with low-level control because it's so much easier to get into than C/C++ and others.

All of that together provides an almost unprecedented boost to the Rust community in many directions. While most interesting things are happening with below-application-level software, these things are getting easy to use from your application-level code with reasonable defaults while also providing facilities to tweak anything in your stack without leaving the comfort of Rust.

Rust is already used for backend, GUI, gamedev, blockchains, data processing, machine learning, embedded, devops and infrastructure, operating systems, security applications and so much more. There are great libraries for a whole lot of things.

everything everywhere all at once

The coolest thing - usually real-world IT solutions rely on at least several disciplines mentioned above and with Rust you can have them all in one language to share types, business logic, and even engineers. Such uniformity also enables much easier overall integration than having, let's say, a React frontend, a Python backend, some data pipelines in Java, and Go code that manages the deployments. This gives Rust a significant advantage over most PLs except C/C++, but I think Rust wins over them in many other aspects and especially developer experience.

becoming a rustacean

Rustacean is a common term for software engineers with Rust experience. They are usually born between the pages of The Rust Book; their natural habitats are Docs.rs, Github, Reddit, and Twitter, and more often than not they are pretty friendly geeky creatures. They are using Crates.io to get nutrition and their favorite snacks can be found inside the examples folders in the crates' repos. But beware - some of them are so rusty that they become salty if they encounter specimens of other kinds.

First, you'll need to get some rust on your metals. The most common way to do that is by using rustup - toolchain installer and manager. It will include the compiler, package manager, linter, and other things. Basically a one-stop-shop for Rust tooling. The excellent quality of Rust documentation, compiler error messages, and community support together with an easy setup thanks to rustup lowers the bar for entering this rustacean territory.

Next, you'll need the development environment. Then I'd highly recommend installing the rust-analyzer extension to get rich language support. It integrates well with VS Code, Vim, Emacs, and others.

If you want your project rebuilt and rerun after every change you should try cargo-watch. Also, since Rust is a great fit for the development of CLI tools there is an abundance of them for all kinds of needs.

Last but not least - just start building anything. Get used to the compiler and ownership rules. Get deeper intuition of smart pointers. Don't try to understand all the Rust features right away - focus on the stuff that you need for your project, eg async/futures if you're building something concurrent like web servers, and gradually expand your understanding. And unless you have solid C/C++ experience - don't expect to get used to Rust in a couple of hours. Give it some time, it's worth it. And maybe try prest, I'm doing my best to make it really easy to build apps with. Have fun!

v0.4.0
made by Egor Dezhic