by filleduchaos | 2025-11-08 22:42:34+00:00
The very first line of the documentation of Rc (https://doc.rust-lang.org/std/rc/index.html) describes it as a single-threaded reference counting pointer. That alone should be enough indication to any dev that can actually be trusted with multithreading that it isn't going to be fit for purpose for sharing data between threads, whether the compiler yells at you about it or not. They should not need it explained to them that a program that shares non-atomically reference counted pointers between threads (while relying on their reference counting behaviour) is not a "correct program".

What actually happens in practice, as you've alluded to, is that people who simply want to continue writing software the way they always have (but in Rust, whether due to FOMO or necessity) hear "use Rc/RefCell/Cell if the compiler is yelling at you" and then start slapping those constructs everywhere to avoid having to read too many of those pesky compiler errors, without ever considering or understanding what they actually are. And then when an architectural change is needed - in this case, rewriting a single-threaded program to be multithreaded - suddenly it is also the compiler's fault because the original program was not written with a single thought towards multithreading.

Whether you are using a compiler that yells at you about it or not, properly threading any single-threaded program that was similarly written without concern for parallelism (say, a C or C++ program that also liberally used non-thread-safe reference counted pointers) would take a non-trivial rewrite. For some reason, the fact that Rust - a language that explicitly sells itself on catching such problems at compile time - actively surfaces the poor architecture as errors as opposed to leaving the user to hunt them down themselves is supposed to be considered Bad™.

The funny thing is that there actually are real examples of problems with the borrow checker which need to be fixed by the language team (for example async closures and async Fn traits are very much a work in progress). But "I used explicitly thread-unsafe constructs and now I have to refactor my code to run properly on multiple threads" is simply not one of those problems no matter how you spin it.

> Nannying is when you are constantly being told what you cannot do. It might not even ensure safety, but definitely restricts your freedom.

Nannying is also literally the job of looking after a child [that isn't yours], which is a definition that in my opinion applies with users who don't want to learn how to use a tool as prescribed (this part makes perfect sense to me and is completely fair, nobody HAS to use Rust or any other language or tool regardless of what its diehard fans think), yet also want it to protect them from their own mistakes and lack of foresight when they make a mess of using it (this part makes no sense to me).

To put it very bluntly (or rudely, or however else you want to read it): *all* languages (natural and programming alike) have constraints, that is what makes them languages. It's perfectly fine for the conversation to begin and end at "I don't like Rust's borrow checking rules". Sure, then don't use Rust! There are several languages that I simply don't use because I don't like something or other about them, even things as trivial as significant whitespace in Python. I don't want to deal with it so I simply...don't. But approaching a language in oppositional defiance and then complaining that you got the fight you were looking for makes little sense to me.