Rust language – the most loved language of them all

Rust language

Intro

When reading the latest tech news it’s relatively easy to find a post about a big IT player embracing Rust or how Rust is loved by developers.

Stack overflow surveys always show Rust as the #1 loved language, every year since 2016. However, in terms of popularity it’s far behind other languages, sometimes not even making it into the top 20.

As of now, July 2020, it has moved from number 33 to 18 on the TIOBE index, so it may or may not improve in standing in the future. The trend is positive at the moment.

There are programming languages for business application programming such as Java, C#, Python, and Ruby, and programming languages used mostly for system level programming such as assembly language, C, and C++.

When building operating systems, servers, databases and applications that need to work very fast and minimize resource usage (such as web browsers on large computers or software for small underpowered IoT devices), system languages are being used.

Let’s take a look!

To change or to pretend a change – that is the question

 

The promise

Rust promises to be the representation of the next generation of languages.

This means first of all, getting rid of the known problems with previous generations and delivering a fast modern language which is expected to become a language for tens of years to come like C, C++, and Java before it.

 

Memory problem fix

About 70%-80% of security related issues and programming errors are related to the management of memory.

C language for instance, is very liberal when it comes to memory access, so we’ve got thousands of vulnerabilities related to buffer overflows, too easily accessing memory to read the secrets (passwords, tokens), injecting malicious code, etc.  It’s a nightmare for the majority of software that we use today and we use it everywhere . . . on billions of computers from large servers to the smallest intelligent sensors.

There are many workarounds and solutions for that, but Rust creators decided to break the legacy and do something from the ground up to prevent these types of attacks now and in the future.


The first steps

brew install rust ⇐ don’t do this !

No, that’s not a good idea, as rustup will be missing. I recommend strongly visiting:

https://rustup.rs/#

And running the script (MacOS, Linux):

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Or downloading Windows .exe installer rustup-init.exe 

Create folder

cargo init

cargo build --release

 

Interesting facts

Instead of another intro to the language, I’ll like to share with you some interesting facts that are specific to Rust, assuming you know one of the application level C-derived languages such as Java, C#, JavaScript or C++.

  • Garbage collection – there’s no runtime garbage collection such as in Java or C# , and . . . you don’t have to do it yourself. Memory cleaning routines are added during the compile time and thus Rust delivers deterministic object removal from the memory (no GC pauses anymore); it looks like a perfect combination – you don’t have to do it yourself and it’s done automatically at the compile time.
  • Performance – Rust is considered to be “blazing fast”. The tests prove it’s even faster than Go and often even faster than C or C++ equivalents (https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/rust.html), so the speed advantage is definitely there. It has to be, otherwise it would be hard to justify a new language for system programming. Speed is essential. The code is compiled to the machine level running on a bare OS, so no virtual machines or interpreters here.
  • Package manager – cargo – of course there’s a package manager like with any other language.
  • It comes with its own updater (rustup).
  • Semicolons are required in Rust.
  • Very strong typing is needed at the compile level, for instance you cannot just print numbers with println!(10).
  • Variable type inference – it is here with the let keyword.
  • Variables are immutable by default – once you set the value, you cannot modify it, which is something similar to const in JS. You have to enable mutability with let mut (special keyword for enabling modification of variables).
  • So what about const? It is available as well.
  • Let can initialize multiple variables at the same time.
  • No camelCase for variables, underscores rule the Rust world;
    let my_name = “Jacek”;
  • Assertion testing is built-in with assert_eq!
  • There is no implicit boxing of the types.
  • Tuples – grouped together values of different types (max 12 elements).
  • Arrays length is fixed, so it is not dynamic nor immutable by default.
  • Vectors are growable and can change in size.
  • No ternary operators such as  binaryCondition ? valueReturnedIfTrue : valueReturnedIfFalse;
  • Functions, without requirements of the classes, are there.
  • Closures exist.
  • Functions can be added to structs with the impl keyword; self is equivalent of this keyword.
  • Functions don’t have to return (the expression is unnecessary).
  • Inheritance? There is no inheritance as the composition over inheritance paradigm is present, but . . . we have traits. Traits are language construct and they are something between interfaces known from the object oriented languages and mixins. They define a set of methods that a type must implement.
  • Rust can be compiled even without a standard library to make the binaries even smaller and require less memory.
    #![feature(start, libc, lang_items)]
    #![no_std]
    #![no_main]
  • Generic functions can be type-checked at the compile time.
  • Generics result in separate code generation – more optimized but larger binaries. The type erasure mechanism known from Java is not present in Rust.

 

Traits example

Traits are not unique to Rust, but Rust is one of the few languages that support them directly. 

struct Car { name: &’static str, licence_id:&’static str, max_speed: u16 } 

trait Vehicle
      // Static method signature; `Self` refers to the implementor type.
     fn new(name: &’static str, licence_id: &’static str) -> Self;

    // Instance method signatures; these will return a string.
    fn name(&self) -> &’static str;
    fn licence_id(&self) -> &’static str; 

   // Traits can provide default method definitions.
   fn identify_yourself(&self) {
          println!(“{} has id {}”, self.name(), self.licence_id());
 }

   fn drive(&self, distance: u16) {
       println!(“Driving {} identified as {} for distance of {} km”, self.name(), self.licence_id(), distance);
   }
}

// Implement the `Vehicle` trait for `Car`.
impl Vehicle for Car {
     // `Self` is the implementor type: `Car`.
    fn new(name: &’static str, licence_id: &’static str) -> Car {
        Car { name: name, licence_id: licence_id, max_speed: 180 }
} 

    fn name(&self) -> &’static str {
         self.name
   }

   fn licence_id(&self) -> &’static str {
         self.licence_id
   }

   // Default trait methods can be overridden.
   fn identify_yourself(&self) {
         // cars also include their maximum speed
        println!(“{} has id {} and maximum speed of {} kmph”, self.name, self.licence_id, self.max_speed)
   }
} 

fn main() {
// Type annotation is necessary in this case.
     let mut car: Car = Vehicle::new(“AvengaElectric”, “AVENGA2021”);
    car.identify_yourself();

   // invoke default method from the trait Vehicle
   car.drive(50);

   // after some tuning the maximum speed has been increased
   car.max_speed += 50;
   car.identify_yourself();

   // invoke default method from the trait Vehicle
  car.drive(150);
}

Results in:


Adoption

Mozilla

Rust was born at Mozilla Research and it is used in Firefox browser engine implementation, both the old ones (Gecko) and new one (Quantum engine).

So if you happen to use Firefox, you use software written in Rust.


Tor

The most famous web anonymity network engine is also written in Rust, for its performance and security properties.


Microsoft

Microsoft was inspired by Rust and started to create its own language based on Rust, called Project Verona. 

Microsoft attempts to eliminate memory-related bugs so common in software written in C or C++, when it’s up to the developers to properly manage memory. It means both memory leaks and even worse – memory related security exploits. They say they “reached a wall” with C and C++.

Microsoft is also experimenting with Rust for device drivers, like with their Rust library for Windows Runtime (WinRT). 

 

Amazon (AWS)

Amazon is a new supporter of Rust language. They use it for their most performance sensitive services such as AWS Lambda, EC2 and S3.


Deno

Deno is an attempt to write a new NodeJS engine that works with TypeScript natively instead of Javascript for its class support and type safety, and it is better suited for large projects. Even though it’s based on a V8 JS engine written in C++, the project is based on Rust. One of the reasons, beside the very good performance and memory safety, is the support of multimodular applications thanks to “crate” which is a Rust solution that manages software libraries.


Google

Google decided not to support Rust for it’s new OS, called Fuchsia, because of its lack of popularity in the development community.

Browser wars. Should Apple and Mozilla give in at last?


Linux

Members from the kernel maintainers community are looking for an alternative to C.  A shift from C will be a very long process, but they are already experimenting with Rust for the development of device drivers (modules).


Nice but changing too often?

One of the criticisms against a wider Rust adoption is that it has changed significantly several times already, which is often interpreted as a sign of platform immaturity.


WebAssembly – the primary choice

So, it’s not just a system and advanced native apps programming. Rust is the primary language for building Web Assembly applications. So there’s a clear presence of Rust in the application space, and learning Rust can also be useful for building advanced applications targeting modern browsers.

Rust is recommended as it’s an easier language to learn than C++, but delivers the same runtime performance.


Rust vs. Go

Go is another interesting language. The differences between them are:

  • Go is widely considered to be much easier to learn. Developers using both Go and Rust say that Go is a matter of days to start and weeks to master, but in the case of Rust, it is a matter of weeks to even start and years to master.
  • Go is slower, but still very fast. Users of both say that the slightly slower performance is rewarded by simplicity and a much lower learning curve.
  • Rust is much more “feature rich” and more ‘modern’ which enables the language constructs unavailable in Go, and it even supersedes the latest versions of Java and C# languages.
  • Nil:  the “null problem” still exists in Go and it feels very much like “last generation” because of that, which is why Microsoft preferred Rust in their implementations over Go.
  • The Rust compiler is unforgiving and even C++ or Java seem to be more tolerant.
  • The Rust object ownership concept is unique and hard to understand for newcomers.


Rust vs. Java and C#

Rust is almost non-existent in the back end programming of business applications, however it’s easier to find on the front end in Web Assembly applications facing business users.

It is perfectly fine to write API endpoint implementations in Rust, connecting to classical databases (PostgreSQL, etc.). There are libraries supporting that and it’s a popular way to create business APIs at the moment.

 

Comment from Dmytro Parasochka (Avenga Developer)

What do you like about Rust?

Algebraic data types, pattern matching, the macro system, doesn’t have null references, great errors explanation with advice on how to fix it.

 

What do you dislike about Rust?

A learning curve, module system (it pushes you at the start of the project to plan the structure of the project and dictate how to do it), lack of good IDE, added language complexity by ‘borrowing’ mechanism.

 

Would you like to use Rust in your next project?

I wouldn’t. I’ll spend a lot of time learning how the Rust memory safety features work and fighting with them, instead of working on a problem.

Once I’ve tried to recreate a simple VM that I wrote in Python in 1 day and in Rust I spent 3 days working only on disassembler functionality I tried to figure out how the module system, ownership, and lifetimes feature works.

 

Future

Rust is liked by many developers when they fill in surveys, but it’s much easier to ‘like’ the language online than invest time and use it in real world applications. Especially when it means abandoning the well known ecosystem of tools and . . . habits.

Our choice at Avenga, so far, is clearly Go over Rust for our advanced services programming, especially in our products (wao.io and couper.io) when speed and the memory footprint are critical, yet we admire the modern feel and safety features of Rust. 

There are many fans of both in our dev community here.

Get software engineering help
Start a conversation. Use the contact form below and we’ll get back to you shortly.
Back to overview