No, I’m not getting old. I mean - yes, technically I’m aging and getting older in this very minute. But this blog entry is not about me getting old and senile. It’s about a programming language I recently started to learn: Rust.
About three months ago, right after the new semester started, I was looking for a new programming language to learn. I was getting tired of writing every project in Python. I wanted a language that has a strong type system, is fast (yes… “fast” is relative) and compiled. Two friends of mine (Hendrik and Kilian) hinted me towards Rust which they claimed to be a really nice language with beautiful syntax.
First Steps
So I chose Rust over Go (which I might look into later) and started to learn it by reading the book1, a piece of literature written by the (who? Rust Community or Devs?) which carries the name “The Rust Programming Language”. After a brief overview you are directly being thrown into a relatively practical example by writing a small random number generator to get to know a few basics about the program structure and see some things that you will learn in the following chapters.
It felt really good to see something practical before diving into theory. And even though it was a little bit overwhelming to use the Rust Package Manager (cargo
), match
statements and error handling right in my first program in that language it felt so much better than writing a plain “Hello World“. Not just because every single step towards the final Guessing Game is being explained in detail.
This is what Rusts interpretation of a “Hello World” (aka guessing game) program looks like:2
extern crate rand;
use std::io;
use std::cmp::Ordering;
use rand::Rng;
fn main() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1, 101);
loop {
println!("Please input your guess.");
let mut guess = String::new();
io::stdin().read_line(&mut guess)
.expect("failed to read line");
let guess: u32 = match guess.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
println!("You guessed: {}", guess);
match guess.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
The following chapters of the book are each dedicated to a certain characteristic of Rust. These points interested me the most:
-
Every variable is by default immutable. At first, this sounds a little bit stupid. Even though other popular languages like Swift encourage you to use immutable values, enforcing it like this seemed a little bit over the top for me. But it makes sense, when you think about it: One of Rusts primary goals is safety. Having immutable values by default minimizes the risk of accidentally overwriting a value you wanted to keep or never intended to change.
-
Rust uses a system called the “Ownership System” to achieve Memory Safety. Therefore, every variable binding in Rust has a so called Ownership: It can be bound exactly once, when you write something like
let x = y
, y is being moved to x and no longer available.
If your binding is going out of scope, Rust will free the bound resources.
To make this system work, Rust has introduced the possibility to “borrow” a variable binding to another function and keep the binding even if the function you called returned. This is perhaps one of the most difficult things in Rust and from time to time I found myself “fighting the borrow checker”, who checks at compile time if your code is valid in terms of the Ownership System. You can read more about the (in)famous Borrow Checker here.
Further Progress
After I had read half way through the book, I started to write some small programs to get some practical experience. I tried something I did several times in Python: Writing a parser for our canteen using OpenMensa. But it turned out that deserializing the returned JSON message was harder than I thought since this required either a lot of hand work or the use of Compiler Plugins, which required (at least back then) Rust Nightly.
So I tried some other things.
So far I’ve written some small things like a bitly link shortener and a program that uses hyper
(a http library for Rust) to get the status of our student representatives office and display the status as an AnyBar dot.
I also wrote my first crate (that’s what libraries in Rust are called - and yes: they are being shipped via Rust’s package manager: Cargo): anybar-rs
, which communicates with the AnyBar dot in your status bar to display whatever you want. Which brings me to my next point:
The Community
Probably one of the most fascinating things for me was the Rust Community itself. Rust has such a healthy and friendly community, it surprised me! After I published my first crate to crates.io, I tweeted rather proud of myself what I had done and the reaction was terrific.
I know that a few replies and stars (those are called hearts now) are not that special. But I was not used to that kind of community. I expected nothing when I sent out the tweet. I never tweeted about Rust, neither am I some kind of well-known person in the Community and so I didn’t think that anything would come out of this. But the encouraging reaction from other Rustaceans felt really good and someone even took the time to look over the few lines I wrote and gave me feedback.
This was just overwhelming.
So, how’s it?
All in all, Rust is a really cool language with a damn cool community and really nice syntax. It gives you the impression of being developed by following a well thought-out concept because it is just so organized! 3 Even though Rust’s still a little bit rough around the edges, I’m looking forward to dive deeper into it! You will sooner or later be hearing more from me about Rust. ;-)
-
You can read more about it on the tutorial page! ↩︎
-
I know, that’s an advantage every new language will have compared to languages like C++, which have been out there for quite some time now. But still! ↩︎