My mission as a software developer is always to build a product to be proud of, a product the company is proud of. In my daily work I use a MacBook Pro, I write C# using .net core in Intellij Rider. It’s awesome!

There’s a lot to be said about C#, it’s a beautiful language. The fact that I can use my MacBook is to me a big step forward for Microsoft and C#. However, it’s not C# that I’ll be writing about now. I’ve previously written a post about why I choose Rust and why I think it’s a language worth having a look at.

I’ve talked about how Rust is very strict and exhaustive; this is something I’d like to explore more.

In the previous article I mentioned two ways of passing data between methods, the “&” for lending value or simply giving the value. These can be called pass-by-reference and pass-by-value.

Though it’s true that the basics is two ways, there are more ways of expressing intent. Rust is immutable by default, meaning that if you simply create a value “let age = 2;” the age can’t be changed. To make this value changeable you need to say “let mut age = 2;” where “mut” is what we are looking for here. Knowing this, if we want our receiving method to change the age-value we need to specify that. This is done through “do_it(&mut name_of_value)”. Mutability in Rust is exhaustive, but it also means that you protect the data from unwanted changes. Here’s a small list of how you can pass values:

Pass-by-reference 

• fn pass_by_ref(i: &mut [usize]); (Give me a ref to the value and let me edit it) 

• fn pass_by_ref(i: &i32); (Give me a sneak-peak at the value) 

Pass-by-value 

• fn pass_by_value(mut i: i32); (Give me the value and let me edit it) 

I mentioned exhaustiveness as a key factor of Rust before. This is just one example of how you always need to specify intent. Another way that Rust is exhaustive is through completion, just like another language called Elm. When iterating over a list of items or matching over an enum, you always must specify either a default case or finish up all cases, otherwise it won’t compile.

Knowing this, you might think of Rust as being too much for the user to think about. Why do I need to specify everything? – Because you know the intent. Since programming in general is quite hard, we’ve always tried to keep it as simple as possible. Looking at JavaScript, C# or Java there are Garbage collectors, linters and patterns to solve what’s built into Rust. It does not matter if you clean the values or even finish the iteration. You get runtime errors if it can’t handle the case you specified. This is not the nature of Rust.

Though Rust helps you a lot when it comes to completion, special yet simple syntax and of course a brilliant compiler that gives hints that other languages could not do. C# has a lot to learn when it comes to helping us developers. “There’s an unhandled exception in production” is not a phrase that will be mentioned often for an app written in Rust.

The journey continues, what’s the purpose of exceptions? Why not force correctness?

Author: Alexander Herlin, Developer at One Agency