Despite its name, the Rust programming language has never looked so shiny and new. Way back in 2016, Stack Overflow’s annual survey of developers crowned Rust the “most loved” programming language. They voted their love again in 2017, 2018, 2019, 2020, and 2021. Presumably, when 2022 rolls around, that devotion to Rust will persist.
Not that the Rust community is resting on its laurels. No, if anything, Niko Matsakis, co-lead of the Rust programming language project; Shane Miller, chair of the Rust Foundation; and other key members of the Rust community are working hard to ensure Rust will remain beloved for years, even decades. One way they’re doing this is through the Rustacean Principles.
Although the Rustacean Principles could be dismissed as mottos to be casually discarded whenever fluffy ideals meet brutal reality, they actually function as robust guides to Rust’s long-term development.
Principled behaviour for Rust
Given that Matsakis and Miller both work at AWS, it’s not surprising that the principles started out as a spin on Amazonian tenets. Amazon uses tenets to guide decision making. In the case of Rust, Matsakis and crew may have started with Amazon-esque ideas, but they’ve since evolved them to keep the Rust community on course to empower “everyone to build reliable and efficient software.”
What are these principles? In building Rust, its community balances different, mostly complementary, principles of what Rust should be:
- “Reliable: If it compiles, it works.”
- “Performant: Idiomatic code runs efficiently.”
- “Supportive: The language, tools, and community are here to help.”
- “Productive: A little effort does a lot of work.”
- “Transparent: You can predict and control low-level details.”
- “Versatile: You can do anything with Rust.”
I said the principles are “mostly complementary” because, as Matsakis points out, “These properties are frequently in tension with one another.” What happens when making Rust reliable conflicts with making it perform well? When two principles conflict, he notes, “We tend to give the edge to those goals that come earlier in the list over those that come later.” Reliability, in other words, is more important than versatility. Even so, “while the ordering is important, it’s important to emphasise that for Rust to be successful we need to achieve all of these feelings at once.”
For those looking to the future of Rust (currently at Version 1.54, but evolving fast), the list and its order of principles offer a great guide for what to expect from the Rust community going forward. It’s perhaps worth looking at a specific example to see how this plays out in practice.
You’re so reliable
As detailed in the principles, Rust’s reliability is “most often at odds with making Rust feel productive and supportive.” Why? Because Rust relies on cross-checking across the system to ensure overall consistency. This principle ensures developers can invest great confidence in systems built with Rust, but it does come at the expense of other principles. A great example of how the community grappled with the balancing of different principles is described in the write-up of the eventual adoption of the “Truncate at Drop unless Copy” rule.
How do Rustaceans build reliability into Rust? In two primary ways.
First, Rust relies on Type safety. This means that “Rust code is free of ‘undefined behavior,’ which is the term that compiler authors use to refer to things like segfaults, data races, and out-of-bounds memory accesses.” Rust’s community will never accept “almost safe” APIs. It’s not good enough that the code works so long as everyone does rational, reasonable things. The code has to work. Because this can grate against the principle of productivity, Rust works hard to deliver informative documentation and error messages to try to mitigate the potential to burden other Rustacean development principles.
The second way Rust helps deliver reliability is by consideration of all cases. What does this mean? “Rust doesn’t hide error conditions and encourages listing all possibilities explicitly (or acknowledging that something is elided).” Here’s how Rust accomplishes this sub-principle:
“Rust...adopts the approach pioneered in functional languages of returning an enum. The
Result enum allows one to signal an error in a way that forces the error to be considered. Still, the most common way to handle an error is to propagate it to your caller, and in order to feel productive, it’s important that this operation be concise. Rust’s
? operator was added to restore productivity while ensuring that error paths are still visible to users and are not completely overlooked.”
As may be evident, things like great error messages aren’t really a function of the language itself, but rather of community behavior that helps ensure overall reliability for Rust. Some of these principles are expressed in code, in other words, while others are delivered through community behavior. As such, it’s perhaps not surprising that the Rustacean Principles outlined by the Rust community also include a section on “how to [be] Rustacean”:
- ”Be kind and considerate”
- ”Bring joy to the user”
- ”Show up”
- ”Recognise others’ knowledge”
- ”Start somewhere”
- ”Follow through”
- ”Pay it forward”
- ”Trust and delegate”
Rust has succeeded, in significant part, because its community has not been willing to sacrifice the central tenets of what Rust means. As Oso CTO Sam Scott once told me, Rust is “systems programming with guardrails.” Those guardrails turn out to be critical for Rust development and adoption. They’re preserved by the Rustacean Principles and point the way to what Rust will look like in the future, even as it evolves.