Why Rust, and how to think about it
Every language makes a trade. Python trades speed for ergonomics. C trades safety for control. Rust’s pitch is that one of those trades was never necessary: you can have memory safety without a garbage collector, if the compiler is willing to do a lot more work at compile time — and if you’re willing to tell it more about your intentions.
That second clause is the whole learning curve. Rust isn’t hard because the syntax is exotic; it’s hard because the compiler enforces rules about who owns what that other languages leave implicit. Once you internalize those rules, the errors stop feeling like fights and start feeling like code review from a very fast, very pedantic colleague.
Setup
One command installs the toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shThat gives you rustc (the compiler), cargo (build tool and package manager), and rustup (toolchain manager). You will almost never invoke rustc directly — cargo runs the show:
cargo new hello && cd hello
cargo runThe first program worth reading
Skip “Hello, world” — you can guess it. Here’s the smallest program that shows Rust’s personality:
fn main() {
let name = String::from("Sarmad");
greet(name);
// greet(name); // <- uncomment this and the program stops compiling
}
fn greet(name: String) {
println!("Hello, {name}!");
}Calling greet(name) moves the string into the function. After that line, main doesn’t own it anymore, and the compiler will refuse to let you use it. That refusal — checked entirely at compile time, costing nothing at runtime — is the core of the language. Everything else in this series is a consequence of it.
Next up: what “ownership” means precisely, and how borrowing lets you share values without giving them away.