A few nice Rust features from JVM/C perspective
Rust language popularity is growing. It is used in various tooling applications, Linux kernel, Android, and other systems. We have written more about that in our IT trends 2023.
Rust is a relatively new (compared to e.g., C or Java), statically typed language. That brings some chances and challenges. When creating a new ecosystem from scratch, you don’t have to keep any backward compatibility. It can be created based on lessons learned on other platforms introducing more radical changes.
Today let's talk about a few Rust traits or features which look interesting at first sight.
Null’s are a nightmare for a lot of languages. In Java, projects tend to leverage defensive programming practice to check all incoming values if it is for sure they are not null. In Scala, as the best practice, nulls are not used, however, they still exist on the language level due to JVM and compatibility with Java libraries. Tony Hoarse considered the null introduction in ALGOL as his “billion-dollar mistake”. Probably everyone working with Java has seen at least once a NullPointerException. On the contrary, in Rust, you won’t find them. Every case other languages handle using null is handled here by an Option enum.
Immutability by default
In Java, variables are mutable. You can find projects leveraging the
final keyword everywhere, trying to make them immutable, however, it still does not give solid guarantees (since objects assigned to a given final variable can have mutable fields). In Scala, mutability is a bad practice. Case classes,
vals are immutable, but if you need you can use mutability. Rust follows the same way, all variables are immutable by default. Why? Let’s answer with a quote:
Immutable objects are always thread-safe. - Brian Goetz
If you require mutability, you can achieve it by using additional modifiers.
Tooling - code formatting
Rust tooling has built-in documentation (Rust book) and a code formatting tool. In Java I think there isn’t any standard for code formatting. In Scala, the scalafmt tool is very popular, but still, not every project uses it. In Rust, it is just built-in, so the adoption may be much easier. Cargo also includes Clippy, which is a powerful linter for Rust.
The JVM memory model is a magical place. Learning about it and how it works may blow your mind. Concurrency using the
volatile keyword is not easy. The practical order of operations is not so clear. In C, it is not easier: you have to deal often with race conditions, etc.
Rust takes a totally different approach. It introduces a few concepts (which often were known before but not used in the most popular languages) - lifetimes, borrowing, immutable references. They all together bring compile time verification if your code is safe. Rust prevents you from doing things which could lead to runtime issues.
When using JVM, all project dependencies are put on the project classpath. Project depends only on one specific version of the given library. When a conflict appears, a newer version is chosen. However, such a situation may lead to runtime issues, saying that some class or method was not found.
In Rust, Cargo understands Semantic Versioning. The crates your project depends on may depend on different versions of the same library. The compiler will handle that for you. What is more, it is possible to have two different versions of the same library used explicitly in your source code by using dependency rename feature.
Java has a few types of loops, e.g., traditional for and foreach. I remember old debates about foreach being slower! Quite similar articles appeared around Java 8 when the lambdas were introduced. In Rust, the situation is a bit different. The closures and iterators are implemented so that the runtime performance is not affected. Rust aims to provide zero-cost abstractions so that more advanced features do not affect runtime and are handled compile time instead.
Rust is intriguing. It solves some of the pains often met in the JVM world. Its design choices also show clear advantages over e.g. C or C++. It is not the easiest language, but definitely powerful. It has now found its niche as a C replacement in various tooling applications or system-level implementations. Rust is thriving, and you can find a lot of web frameworks for it as well. However, it may be more difficult and time-consuming to build a simple web application in Rust than e.g., in Java. If you don’t need its performance, then Java/Scala may be just enough.
Reviewed by: Jakub Antolak