0%loading

A Love Letter to Rust

Official Rust Logo

There is an old aphorism in software engineering that says: "A good language is one that makes you comfortable." For years, I genuinely believed that. I was comfortable in high-level languages that forgave my oversights, let me pass objects around carelessly, and only blew up hours later in the cold dead of night when code was already running in production.

Then, I decided to learn Rust.

At first, there was nothing romantic about it. There was no spark of love at first sight. What existed was pure frustration, a terminal window flooded with red diagnostics, and a persistent question echoing in my mind: “Why does something as simple as borrowing a piece of data require an essay-length negotiation?”

Yet, the deeper I ventured into the language, the more I recognized something that fundamentally reframed how I perceive engineering: Rust was never trying to make my life difficult. Rust was teaching me how to think.

And gradually, I fell in love.


1. A Compiler That Refuses to Give Up on You

For anyone who has ever wrestled with low-level systems languages like C or C++, compiler diagnostic messages often feel like an indifferent execution sentence. You get an unadorned segmentation fault (core dumped) with zero runtime context, or a three-page template error dump that reads more like an ancient curse than actionable guidance.

Rust is the exact antithesis of that experience.

The Rust compiler (rustc) does not behave like a sterile syntax checker; it feels like an empathetic senior engineer sitting beside you with a warm cup of coffee, gently pointing at your screen, and explaining:

error[E0382]: borrow of moved value: `data`
  --> src/main.rs:18:20
   |
14 |     let data = vec![1, 2, 3];
   |         ---- move occurs because `data` has type `Vec<i32>`
16 |     process(data);
   |             ---- value moved here
18 |     println!("{:?}", data);
   |                      ^^^^ value borrowed here after move
   |
help: consider cloning the value if the performance cost is acceptable
   |
16 |     process(data.clone());
   |                 ++++++++

Look closely at the help: section.

It doesn't merely tell you what broke. It explains the underlying mechanical cause, illustrates the exact point of divergence, and offers a concrete, idiomatic suggestion to fix it. There is immense humility and intentional craftsmanship embedded in that design. The compiler never mocks your confusion; it holds your hand and refuses to let you ship flawed software.

In a craft where developer tools often feel cold and mechanical, rustc’s patience feels strikingly human.


2. Making Peace with the Borrow Checker

The initial stumbling block for almost every newcomer to Rust is the interplay between Ownership and Borrowing. It is an uncompromising reality check for anyone accustomed to sharing mutable pointers across arbitrary boundaries without constraint.

The core rules sound deceptively straightforward:

  1. Each value in Rust has an owner.
  2. There can only be one owner at a time.
  3. When the owner goes out of scope, the value is automatically freed.

Yet the moment you attempt to construct non-trivial data structures like doubly linked lists or cyclic graphs, you find yourself locking horns with the Borrow Checker. You want to borrow data mutably, only to find that another routine is holding an immutable reference elsewhere. The compiler flatly refuses to build.

Early on, I felt this discipline was overly pedantic. Until the breakthrough arrived.

That "aha!" moment happened when I realized what these rigorous boundaries permanently eradicate:

  • Zero Null Pointer Exceptions: The infamous billion-dollar mistake simply does not exist. It is replaced by the explicit Option<T> type, forcing you to deliberately account for absence at compile time.
  • Zero Use-After-Free Vulnerabilities: Memory is never accessible once reclaimed.
  • Zero Data Races in Concurrency: It is mathematically impossible for two threads to concurrently mutate shared state without provably safe synchronization verified before runtime.

The initial friction dissolved into an unprecedented sense of tranquility. When a non-trivial Rust program compiles cleanly, there is an unshakable inner confidence: if it compiles, it will almost certainly run correctly and endure under load.

That peace of mind is genuinely addictive.


3. Zero-Cost Abstractions: Uncompromised Luxury

The affection I have for Rust is not founded solely upon safety; it is equally fueled by raw performance.

Traditional languages routinely force an uncomfortable trade-off: do you prefer modern, expressive, high-level ergonomics, or raw bare-metal execution speed? Expressive languages typically levy a heavy tax in the form of a background Garbage Collector (GC) that periodically halts thread execution. Conversely, ultra-fast languages historically demanded verbose, fragile boilerplate.

Rust systematically dismantles this dichotomy through its philosophy of Zero-Cost Abstractions.

You can write high-level functional code utilizing iterators, closures, pattern matching, and traits with the elegant fluidity of modern languages:

let total: i32 = numbers
    .iter()
    .filter(|&&x| x % 2 == 0)
    .map(|&x| x * x)
    .sum();

Yet the compiler optimizes this expressive pipeline into an assembly loop that executes as fast as—and often faster than—hand-tuned low-level C. There are no hidden heap allocations. There is no dynamic dispatch overhead unless explicitly requested via trait objects. There is no runtime GC daemon stealing CPU cycles behind the scenes.

It represents software engineering in its purest manifestation: mathematical grace on the surface, ruthless bare-metal horsepower under the hood.


Epilogue: Why Rust Reshapes How You Build

Learning Rust is not just about checking off another language on a resume. It feels like acquiring a new cognitive lens through which to inspect every system you architect.

Once you genuinely internalize ownership, lifetimes, and aliasing boundaries, your approach to other languages transforms permanently. You find yourself instinctively querying who owns this chunk of memory, whether a heap allocation is truly warranted, and how object lifetimes flow through the stack.

Rust proves that software engineering does not have to settle for false binaries: between safety and velocity, between strictness and developer empowerment.

If you have never written a line of Rust, prepare to argue with the compiler throughout your first week. But trust the process. The moment you realize what it is fighting so fiercely to protect, you will never view software development the same way again.

And in all likelihood, you will fall in love too.

Subscribe via RSSGet new posts delivered straight to your reader.
Open feed
Logo

© 2026 Raditya Alfarisi

GithubLinkedInInstagramKaggleChess.comHugging Face