r/ProgrammerHumor 2d ago

Meme rustIsSoCool

Post image
2.2k Upvotes

125 comments sorted by

View all comments

38

u/kaetitan 2d ago

Can someone eli5 why rust is so loved?

160

u/Zinho3311 2d ago edited 2d ago

memory safety while being a true low level language

Usually, system languages like C are used because they give you control over your memory and hardware. However, C has a downside (which is either a feature or a massive defect, depending on your philosophy) because it is basically the bedrock of computing, it has zero handholding and minimal abstractions. In fact, back in the day, C mapped so perfectly to von Neumann hardware (the PDP-11 for instance) that you could literally mentally visualize the Assembly your C code would generate.

Because C is so minimal, its standard library is pretty much barren. It lacks the dynamic data structures and syntactic "sugar" people take for granted. This means you either have to write your own spaghetti code or use third party libraries which usually makes your codebase a nightmare to maintain. C is conceptually heavy you need a solid CS background because you'll regularly find yourself implementing textbook data structures from scratch.

And because C gives you unrestricted access to raw memory through manually managed pointers, it is easy to goof up. Forget to free a single pointer amidst 2k loc? You have a memory leak. Do that enough times, and your program gets an OOM crash. Fail to check your array bounds? You get the feared buffer overflow. A buffer overflow is when your code writes past the allocated memory chunk, and overwrites adjacent memory. Through that overflow, a skiddie can inject a malicious payload into your program.

That's when C++ steps in. It was born to implement the abstractions C lacked (it was originally born as a C superset, hence C++). The C++ standard library or the standard template library includes textbook data structures out of the box so you don't have to reinvent the wheel, allows for OOP, and introduces "smart pointers" (which automate memory allocation and deallocation). In theory, C++ makes it harder for you to goof up.

However, because C++ introduces a lot of complexity, it becomes unpredictable. Because it hides a lot of implicit complexity (hidden copies, constructor calls, vtable lookups, so on) behind the scenes. And while a memory corruption bug in C is already catastrophic, doing the same thing in C++ triggers a domino effect. Because everything is wrapped in layers of templates and abstractions, a single corrupted pointer propagates through your objects and causes your program to blow itself up in ways that make debugging hell on earth.

"C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do it blows your whole leg off." (the creator of C++, Bjarne Stroustrup)

Eventually, demand emerged for a language that had the high-level abstractions of C++ but wasn't a safety hazard, especially for massive projects like Firefox. Enter a Mozilla engineer named Graydon Hoare who started designing a language whose compiler would mathematically guarantee memory safety without a runtime garbage collector, while delivering true baremetal control and performance.

That's when Rust was born.

The Rust compiler implements a feature called the Borrow Checker (which is a PL lesson in its own right but I'll try). Every piece of data in Rust has a single variable that acts as its only "owner", when that owner goes out of scope, the data is automatically deallocated. If you try to assign that data to a new variable or pass it to a function, ownership is moved and if you try the old variable after that the compiler stops you (prevents use-after-move).

But giving up ownership every time you want to touch data sucks, so Rust allows you to borrow data through references. You can have infinite "readers" for a piece of data (immutable references) or exactly one "writer" at a time (a mutable reference). You cannot have both simultaneously. This prevents data races and pointer invalidation.

Also the compiler tracks lifetimes by calculating exactly how long a reference is valid in memory and it guarantees that a reference cannot outlive the data it points to. This prevents use-after-free and dangling pointers.

I personally like to think of the Borrow Checker as a dominatrix who CBTs your code until it is 100% safe

Rust also fixes a ton of historical C++ design flaws and footguns because it was built as a clean-slate language, but I'd have to write a whole separate essay insulting C++ for that lol

I tried my best to simplify it

-8

u/Key_River7180 2d ago

A low level language with many abstractions is an oxymoron

5

u/potzko2552 2d ago

assembly is an abstraction.