Definition of Rust
Rust is a compiled programming language with a focus on memory safety and concurrency/thread safety, plus performance. It is a multi-purpose and multi-paradigm language. Instead of providing ever-higher programming constructs, it emphasizes solving long-standing, ‘lower-level’ problems around creating correct and stable code.
The lack of memory safety and corresponding problems like memory out-of-bound errors are the biggest source of security vulnerabilities and cause tremendous risks and costs. The main cause of the issue is the usage of pointers. It is important to realize how fundamental pointers are for programming, even if not used explicitly, e.g. in every string type (more complex types even more so), array indexes, function calls (pass arguments by reference, function pointers, …), and so on.
Rust introduces a strict ownership concept for variables pointing to other memory locations. In a nutshell, only a single variable can ‘own’ and mutate a value at a time. Multiple variables can reference a value only if all of them are immutable variables, i.e. none of them can change the value. The lifespan (‘scope’) during which a variable owns the value is strictly managed; and when the variable's scope ends, the associated memory is automatically dropped from the heap. This can be analyzed (and errors caught) at compile time.
This also means that Rust avoids using garbage collection in most situations. Consequently, Rust language doesn’t include a garbage collector. For more complex memory management, reference counting libraries are available.
The chapter ‘Further information’ below includes a minimal ‘Scope management «Hello World» example’ plus links to a more thorough discussion.
Of equal if not greater importance is the thread safety built into Rust. The same underlying concept of ownership is applied to ensure that unsynchronized write access to data by multiple threads or thread instances (‘data races’) cannot occur.
Rust features the easy creation of threads that run in parallel, managing shared state and enforcing locking of data, making a distinction between thread-safe and thread-unsafe data types, controlling messaging between threads, and more.
The combination of this set of features (under Rust’s slogan ‘fearless concurrency’) together with the memory safety features are unique to Rust.
Rust provides features around object orientation. Complex data structures can be specified and encapsulated by a defined set of functions. Also, there are ‘traits’ (similar to Haskell ‘typeclasses’ and to Go ‘interfaces’) that describe common behavior by defining a set of method signatures that are then implemented on different types. This is not quite the same as classic OO inheritance, and allows duck typing.
Choosing a programming language is about balancing (development time) efficiency and (run time) risk. The higher the risk (the more expensive programming errors are), i.e. the higher the focus is on quality, reliability, and correctness, the more Rust should be considered. This is certainly the case, but not limited to, classic system programming tasks like writing device drivers. Beyond that, Rust is well suited for application programming with the above quality focus, but also if certain non-functional challenges exist, like high-performance or low-memory requirements.
While developing quality code with Rust is a bit more costly (as flaws that would otherwise be caught in run time are already dealt with at compile time), this upfront investment is massively outweighed by the savings in later stages of the software lifecycle.
For many tasks, Rust is superior to C.
Benchmarks return excellent results for Rust on performance. When replacing C/C++ with Rust for system programs, Software AG has not seen a deterioration of performance (outside the margin of measuring error). As an interesting facet of that, Rust has very good energy efficiency.
Unlike earlier improved system languages like D and Nim, Rust seems to have gathered sufficient traction to become the go-to language for the cases described above.
If emphasis is on developer’s efficiency, Rust will not challenge established languages. Python, for example, is dynamically typed, is easy to learn, is brief and elegant and thus easy to read, has a plethora of libraries, …: All this spells ‘efficient coding’.
Regarding the learning curve, the following comment of a software engineer is anecdotal but plausible: ‘For the first week or so, we lost much of our time to learning how [Rust] borrows [that is using references as parameters in function calls] worked. After about two weeks, we were back up to 50% efficiency compared to us writing in Go. After a month, we all were comfortable enough that we were back up to full efficiency.’ Software AG’s own experience is similar, in particular if Rust beginners are guided by in-house Rust ‘champions’.
Market – Current Adoption
Rust is a popular language and has been voted as the most-loved programming language for five years in a row. It enjoys significant momentum with prominent advocates and adopters including Mozilla, AWS, and Microsoft. It has even been used to write an operating system (Redox) which claims to be safer and have less errors than any Unix flavor, due to its microkernel design and usage of Rust.
Having said that, most of the voters liking Rust are not even personally using it yet. It is not in the top 10 of most used languages today. Experienced developers are hard to find.
Market – Outlook
The benefits of Rust are undeniable. We thus expect its success story to continue.
A notable competitor of Rust is Go. It is ahead of Rust in a number of metrics, including adoption. It is easy to learn and thus suitable for developers of all levels of seniority. It also has a focus on concurrency. For server-side applications, where concurrency is often fundamental but other strengths of Rust are of lesser importance, Go might provide higher efficiency with acceptable risk.