Support Ukraine

Carcinization

Rust is a programming language that, like all the up and coming challengers to the C/C++ dominance, tends to polarize.

The core issue doesn't seem to be the language itself - people seem to acknowledge that the language isn't half bad for what it's trying to do. It's reasonably easy, reasonably performant, and has reasonably good tools. What sends people up the walls is the community surrounding Rust - the self-named rustaceans. The rustaceans themselves can't see why anybody wouldn't like them - or love Rust.

It's the curse of a programming language that as it grows it is dependent on a small core of believers who put in the hard work to grow it, write tools, and get mindshare; and all of this while it's not yet generally useful. But equally it is vital that the language doesn't stay in the company of the faithful if it wants to grow big. Most programmers use languages they don't believe in, working for companies who are extremely averse to letting some identitarian movement establish itself in its organization. Rust is probably OK, but nobody wants a rustacean on their team.

What we see here is a language trying to cross a dangerous chasm, being too small to have wide developer and industry support, but with aspirations too big for a small tight-knit congregation of the faithful.

1. The Language Itself

LogLog games wrote what I think is one of the best critiques of Rust in Leaving Rust Gamedev After 3 Years[a]. It comes from the point of actually developing and shipping with Rust, and thus avoids a lot of the very theoretical and academic discussion surrounding the language. If I were to summarize the article, it would be:

1.1. Yes, But Can You Prove It?

What is provably true is less than what is actually true. Therefore, the code that the Rust compiler can prove to be safe will necessarily only be a subset of all the code that is actually safe. Since the language demands that the code must be provably true, you are limited by what the compiler can prove, which puts severe constraints on how you can architect your program. While there is unsafe { ... }, I'd argue that if you're doing unsafe, then you're not really doing Rust. Yes, it saves you from bugs, but a program being bug-free is only one constraint - it must also be finished on time, on budget, and be able to do what it's supposed to do. Constraining it to whatever the current version of the Rust borrow checker is capable of proving isn't guaranteed to help you satisfy those other requirements and may result in the opposite.

1.2. Functionalisms

Rust has, like many modern programming languages, borrowed a lot from functional programming. This is understandable. Purely functional programming is frequently elegant, resulting in code that is easy to understand and reason about. But it does so by having less state, and fails more and more the more state a program has.

Like many functional programming languages, Rust relies a lot on immutable data[b]. This, however, results in a lot of copying since the only way to mutate state in such a system is to make a copy of the original object with the changes. As LogLog games write: many problems are simply solved by extra copying or cloning[*][c] - just like in functional languages. But copying and the resulting memory churn result in worse performance, as many functional programming languages found out.

Another functional programming pattern is where you don't hold on to state but rather pass state around as a parameter, letting it be mutated and passed along. In Rust, this results in context objects[d] being passed around - but more clumsily as the borrow checker must be able to prove the safety of the code.

I don't think these are particularly damning critiques of Rust, as you can still write many interesting and useful programs, but they do point toward one conclusion: Rust will have most, if not all, the challenges functional languages have.