Even non-techies have probably heard of popular programming languages like Java, C++ or Python. However, a new language has been stirring the programming world in recent years. And it might well be on its way to becoming as mainstream as its counterparts: Rust. In this blog post, software developer Andy Brinkmeyer sheds some light on Rust’s benefits, technicalities, and recent implementation in the arculus tech stack.
A Brief Story of Rust
A programmer gets frustrated with a piece of tech. They get home, sit on their computer and try to solve it. This is the origin and story of several software projects and it’s no different with Rust.
In 2006, Graydon Hoare, a Mozilla programmer, was forced to take the stairs to his 21st-floor Vancouver apartment after the elevator software crashed. He knew that such crashes are often caused by software written in C++ or C, which make it easier to introduce memory bugs. And so when Hoare finally got to his apartment, he opened his laptop and began designing a new programming language that would make it possible to write efficient code with improved memory safety. And the story of Rust began.
Seventeen years later, Rust has become one of the most popular languages on the planet. There are 2.8 million Rust developers around the globe, and the programming question-answer website Stack Overflow elected Rust as the most loved language for seven years in a row. Its economic relevance also can’t be questioned. Companies like Microsoft, Amazon, Meta, Discord, and Dropbox have openly talked about how Rust helped improve their system’s performance. And arculus is proud to join the group.
fn main() {
println!("Hello, world!");
}
Example of "Hello, world!" code in Rust
What makes Rust so popular?
The short answer is that Rust addresses common pain points present in other languages while minimising any downsides. For that, it counts on a few main advantages, namely:
- memory safety
- security
- strong community
- faster development
Here is a closer look at what each of them means:
Memory Safety
This feature refers to Rust’s ability to pre-emptively avoid memory-related errors. They often lead to crashes, vulnerabilities, and unstable software behaviour. Unlike C and C++, where manual memory management can cause issues like buffer overflows and null pointer dereferences, Rust relies on three key concepts to ensure memory safety:
- Ownership: Each value has a single owner, making it explicit who is responsible for managing the underlying memory.
- Borrowing: Values can be accessed through references without owning them, which is called borrowing. Strict rules are applied here to ensure memory safety.
- Lifetimes: Ensure that references are not used after the data they point to has been deallocated, preventing references to invalid memory.
As arculus developer Andy Brinkmeyer explains, the Rust compiler enforces these rules at compile time. “This prevents most memory-related bugs, which is great”, he explains. The result is more robust and safe software. That's because in other languages, programmers need to manually ensure compliance with memory safety rules.
Security
Due to memory safety issues being responsible for a major portion of reported vulnerabilities in systems, Rust's ability to eliminate these issues significantly increases cyber security.
Strong community
Rust takes pride in having a “community-driven development process where most decisions are made through open discussion and consensus”. The “Rustaceans”, as the active members of the community like to call themselves, constantly create new documentation, resources and even libraries. This makes the experience of Rust fully collaborative and interactive for developers of all levels.
Faster development
Rust enables faster programming through its combination of memory-safety and expressive syntax. By catching many common coding errors at compile time, the language reduces debugging time, ultimately accelerating the development cycle.
Rust core features
Andy explains that Rust shares many similarities with C++ since both are "statically typed, compiled languages without a garbage collector". Nonetheless, Rust's popularity comes from some of its unique features. Here is an overview of some of the most prominent ones:
Zero-cost abstractions
As Andy explains, “Abstracting away complicated logic and behaviour is one of the ways we make our software usable. Rust has this guarantee that abstracting away all this complicated logic for data types, does not incur extra cost on your compiled program”. In other words, zero-cost abstractions ensure that using convenient and expressive programming constructs, such as iterators, does not result in slower or less efficient code.
Concurrency and parallelism
Managing tasks simultaneously (concurrency) and utilising multiple processors to speed these tasks up (parallelism) are crucial aspects of modern programming. Still, handling them can be complicated and error-prone. Rust, however, makes both processes easier and more manageable. It does this by ensuring that when multiple tasks work with the same data, they can't inadvertently interfere with each other.
Andy explains that Rust makes working with concurrent and parallel code safer, through its ownership and type system. “Since a value can only have a single owner, it is impossible for two threads to own it at the same time. The type system complements this by marking if types are safe to share between threads, through borrowing and safe to send between threads by transferring ownership”, he elaborates. In other words, Rust prevents many concurrency and parallelism errors at compile time, using the same mechanisms it uses for memory safety.
use std::thread;
fn main() {
let v = vec![1, 2, 3];
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", v);
});
handle.join().unwrap();
}
Code snippet showcasing how to move ownership into a new thread. Source: Rust book
Pattern matching
Pattern matching is a technique used to compare data structures against predefined templates and execute specific code based on the matched pattern. It simplifies decision-making by allowing developers to handle different conditions in a structured and expressive manner. Patterns can be as simple as matching specific values. Or as complex as matching the structure of data types like enums or structs.
What sets Rust apart in this regard is its commitment to code safety. Its strong type system ensures that pattern matching covers all possible cases and reduces the risk of runtime errors. Rust’s concise and expressive syntax makes code more readable. It also provides features like pattern destructuring, automatic variable referencing, and customisation options.
Cargo
Cargo is Rust’s build system and package manager. What makes it a notable aspect of Rust is its capacity to handle many tasks. Some examples are building code, downloading the libraries on which the code is dependent, and building such libraries – also called dependencies.
“With Cargo, a Rust project centres around a single configuration file, where you define the properties like name, version, and dependencies. Cargo then handles the essential tasks, like setting up the project, compiling code, and linking build artefacts. In practice, using Cargo often boils down to running a single command like 'cargo run,' which simplifies the entire development process."
Andy Brinkmeyer
Rust at arculus
The Rust programming language has proven to be a highly versatile tool, with widespread applications across various fields. The most prominent ones include Operating Systems (OS), Kernel programming, embedded systems, and cloud infrastructure. And while its numerous advantages make the number of potential Rust applications grow steadily, there is one field in which it still falls short: robotics.
“In robotics, tasks such as perception, path planning, and localisation involve complex algorithms. These algorithms have evolved over a long time through collaboration between academia and industry, and they are typically implemented in libraries”, clarifies Andy. “Many of these essential libraries are intertwined with C++, creating a dependency ecosystem that reinforces its use. Transitioning from this well-established field, where everything you need is in a single language, to Rust can be a significant step. While Rust is gaining traction in robotics, C++ still holds the number one position in this field for now", he concludes.
So why do we use Rust at arculus?
While using Rust in our robots is challenging right now, the language is the perfect alternative component of the tech stack that makes up our fleet software solution. “We need something with high performance that can manage multiple robots simultaneously. But we also need reliability and safety because the customers depend on us not crashing and not having errors in the code. They rely on us for the system to run indefinitely without problems. And that's why we are slowly implementing Rust”, highlights Andy.
Managing the transition
For Andy, what defines the approach to the transition process at arculus is “learning by doing”:
“Of course, people had time to prepare and study the (Rust) documentation. But we at arculus are really hands-on, in quite a literal sense – hands on the project, hands on the work. And in my opinion, contributing very early in the adapting phase to the codebase was the best way to get people up to speed. This approach combined with regular feedback by experienced Rust developers allowed us to quickly adopt it as a language and get everyone all set.”
Andy Brinkmeyer
Learning resources
With such an engaged and supportive community, Rust is arguably one of the most well-documented programming languages – and that includes learning resources. For Andy, the most useful ones can be found on the official Rust project website. “The official Rust book was for me, the perfect mix between theory and real-world examples. But I also learned a lot through the other resources on the website, like Rust by example”, he concludes.
exit()
To sum up, Rust has emerged as a robust and adaptable programming language that is gaining recognition across various industries. Its origins trace back to addressing the need for safer and more efficient software, a mission it continues to excel at. From memory safety to security, a reliable community, and enhanced development speed, the language offers a compelling package for software developers.
As the arculus team integrates Rust into the tech stack, it leverages the language's exceptional qualities to ensure high performance, reliability, and safety in our software solutions. While the transition is ongoing, we are committed to the "learn by doing" approach, harnessing the wealth of resources the Rust community provides. Rust's journey at arculus reflects its evolution as a language that meets and exceeds modern software development's demands.