My experience with Rust as a programming language, prior to the start of this journey, was mainly a need-basis, incomplete and barebones one. I worked on a project as part of my internship @ Akamai, that required me to use the Cloudflare quiche library to build a client capable of performing TLS 1.3 0-RTT Data requests. While I did build it, a lot of the code I wrote was haphazard, and I didn’t really know why or how I was doing things, nor was I conforming to ‘idiomatic Rust’.

It’s been over a year and a half since then, and now I’m determined to formally learn Rust, the right way. This blog will detail my journey in doing so.

The Rust documentation offers a beautifully curated ‘book’ that acts like a roadmap in understanding the language and what it has to offer. Brown University has prettified it and added a bunch of bells and whistles to make what I call the ‘Brown Book’ - this Brown Book is what I’m going to be using as my map.

I’m going to be using this space mainly to write down thoughts about whatever section I complete at whatever point in time. These thoughts may be rants, comments, opinions, jokes, or just plain ol’ infodumps. I’m primarily writing this to keep myself accountable.

Chapter 1. Getting Started

Installing Rust for me was a two-step process - installing rustup and installing cargo, since I had a linker already (anyone who has gcc or clang will have one.)

The cURL to install rustup:

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

strikes me as odd - why force TLS 1.2, I wonder?

rustfmt seems like a super useful formatting tool - I will be using it extensively.

Printing in rust seems to be most easily done via macro - println! (the bang is part of the macro, not me being excited.)

Chapter 2. Programming a Guessing Game

Why do we have JavaScript style ’let’, with type inference happening despite being a statically typed language? :’) I’m already not a fan of C++’s ‘auto’ :/

There’s a lot of chaining involved in Rust. Again, reminiscent of Javascript.

Right now, the whole concept of mut needing to be explicitly mentioned to make a variable mutable feels odd. Why not stick with using const if it needs to be immutable, and default to mutable otherwise?

1..=100 - what is this range syntax 😢

match seems the equivalent of the C++ switch-case, but it works a little differently.

A lot of library functions seem to return Result enums. This consists of Err and Ok. Error handling (a huge selling point of Rust) looks like it’s based off of this. For example, the parse method returns a Result that I have to handle.

let parsed_var: u32 = match some_string.parse() {
    Ok(parsed_val) => parsed_val,
    Err(error) => {
        // Do some error handling
    }
};

This may be getting ahead of myself, but unwrap and expect do this ‘matching’ compactly, if there is no immediate error handling apart from either doing nothing or printing an error message.

let parsed_var: u32 = some_string.parse().unwrap();

and

let parsed_var: u32 = some_string.parse().expect("Parsing failed oopsies");

Chapter 3. Common Programming Concepts

3.1 Variables and Mutability

Variable Shadowing - what even is this?? This feels like someone realised they maybe should’ve stuck with default mutability but had their ego bruised too much. I doubt I’m ever going to use this particular tidbit. The below piece of code feels straight out of a fever (pythonic) dream.

let spaces = "   ";
let spaces = spaces.len();

…just… why??

The rest of this seems vanilla enough, but why. Just… why.

3.2 Data Types

So truthiness is not a thing - fair enough.

This ’tuple’ data type feels kinda odd, I can’t lie. Just give me my struct, man. But I do like that I can just destructure the tuple.

Why can I declare arrays with two structurally similar yet semantically different syntaxes?

let arr1: [u32; 5] // Means an array of u32's of size 5
let arr2: ["Shakaboom"; 10] // Means an array of size 10 with default values as "Shakaboom"

I get that having a default value means you can just infer the type from it but like.. sure, I guess..

3.3 Functions

This ’expression vs statement’ distinction is really lending itself to how rust is setting itself apart from most other languages I’ve worked with. Being able to just return a value from an ’expression’ is pretty wild - it feels like lambda functions simplified.

3.4 Comments

/* Hello everynyan!
How are you Fine Thank You */

// Oh my god!

3.5 Control Flow

The if-else is vanilla ish, with neat interactions with the concept of expressions.

let maybe: bool = if boolean_condition { true } else { false };

The loops, on the other hand, threw me for a loop (get it? xD)

let mut counter = 0;

let result = loop {
    counter += 1;

    if counter == 10 {
        break counter * 2;
    }
};

What is this!? They say the ‘;’ after break is optional, but why? Shouldn’t it just not be allowed, since the last line of expressions when returning a value musn’t have a ‘;’? ;_;

Chapter 4. Understanding Ownership

According to the Brown Book,

Ownership is Rust’s most unique feature and has deep implications for the rest of the language. It enables Rust to make memory safety guarantees without needing a garbage collector, so it’s important to understand how ownership works. In this chapter, we’ll talk about ownership as well as several related features: borrowing, slices, and how Rust lays data out in memory.

Boy am I in for a ride, amirite?

4.1. What is Ownership?

The low-level model is too concrete to explain how Rust works. Rust does not allow you to interpret memory as an array of bytes, for instance.

I’m definitely in for a ride.

Rust does not allow programs to manually deallocate memory. That policy avoids the kinds of undefined behaviors shown above.

Fair enough.

The boxed array has now been bound to both a and b. By our “almost correct” principle, Rust would try to free the box’s heap memory twice on behalf of both variables. That’s undefined behavior too! To avoid this situation, we finally arrive at ownership.

First thoughts - C++ std::unique_ptr and its ‘move’ semantics.

MORE COMING SOON!

Thanks for watching! :D