Skip to content

Instantly share code, notes, and snippets.

@cynthia2006
Created August 30, 2025 13:44
Show Gist options
  • Select an option

  • Save cynthia2006/584f518161cfcba9a745afd94c903304 to your computer and use it in GitHub Desktop.

Select an option

Save cynthia2006/584f518161cfcba9a745afd94c903304 to your computer and use it in GitHub Desktop.

Rust is centred around its grandiose claims of safety, always boasting its guarantees of fearless concurrency, memory safety, zero-cost abstractions and other mumbo-jumbo.

First of all, there's nothing such as zero-cost abstractions. Any abstraction, no matter how close to what its meant to abstract, brings a performance penalty; it applies not only to Rust, but also to its rival languages like C++.

Secondly, concurrency is never a child's play. It maybe easy to spawn a couple of threads to do a task, but it also has to be considered whether that's actually beneficial or even detrimental to performance. The topic of concurrency is complex and hard to get right, and it demands hypothesis, experiments and observations. The algorithm that is designed to do the task in a non-concurrent scenario, may often be suboptimal in a concurrent scenario, and must be modified accordingly, given that it's even possible.

And, I've seen many—if not all—Rust users act with hostility towards unsafe code. I understand that often there's no need for unsafety, but in certain cases it has been shown in the past that performance is achieved through unsafety. And not just that, sometimes unsafety is a necessity, such as when dealing with FFI (Foreign Function Interface). Many take "safety for granted" without considering the circumstances where the unsafe code used to implement the safe interface may nondeterministically malfunction, which is the case with a lot binding libraries out there. Bindings exist because not all code has been rewritten in Rust, much to dismay of the Rust community. Not all bindings are high quality, complete or have excellent test coverage. In my personal experience, most bindings sorely lack (useful) documentation, and require examination of the source of the binding to understand how exactly is it interfacing with the underlying library (perhaps written in C or C++).

People coming from a background in C-like languages find Rust rather hard to understand at first, because in those languages the norm is to manually manage memory or resources (sockets, files, etc). However, Rust is based on the model of ownership and borrowing; i.e. a resource may have a single owner, and it can be mutably borrowed once, but immutably borrowed an infinite number of times. This rule doesn't encompass all use cases however, and concepts such as interior mutability or pinning have to be considered otherwise types such as Rc<T> (reference counted), Arc<T> (atomically reference counted) couldn't be implemented. Pin<T> exists an elusive concept of a pointer to a pinned value, for the sole reason that Rust couldn't afford move constructors like C++ and had to adapt with the fact that all moves in Rust are bitwise memory copies. But, the ownership model is promoted to newcomers as if its infallible.

The Rust community doesn't teach people to consider tradeoffs, and forces a singular authoritative opinion. The whole community thrives on meaningless politics1—always, right from the start. And, god forbid you make a remotely politically incorrect opinion, the entire community would cannibalise you!

And, last but not least, Rust lacks a stable ABI as of now, therefore when you compile a Rust project, all its dependencies must be compiled along with it no matter how large! Apparently, the Rustaceans believe in static linking everything—an excuse they provide for the lack of a (stable) ABI.

Footnotes

  1. https://x.com/rustlang/status/1267519582505512960

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment