Although Rust is certainly capable of becoming a popular and successful language — it’s well on its way already — Java and C++ are absolute juggernauts in their respective areas and they are guaranteed to stay that way because rewriting legacy C++ and Java software is often impractical or impossible.
It’s unlikely that Rust will become “as popular” as C++ or Java without a few things happening first.
This may come as a surprise, since (1) I'm actually a fan of Rust myself, and (2) Rust is consistently voted one of the most loved programming languages in StackOverflow polls. These polls capture popularity among users, and not popularity in general. More people use Python than Rust, but Rust programmers are more likely to be happy with Rust. This shouldn't come as a surprise, because Rust is more likely to be used by choice while Python is more likely to be used by fiat.
When I say “popular” I mean “popular for commercial projects”, not just among the developers who use it because they want to.
Rigorous proof of memory safety.
The Rust creators and community make lots of claims about the memory-safety that Rust provides, and a lot of those arguments make intuitive sense. However, nobody has done a rigorous formal proof that “safe” Rust is memory-safe or thread-safe. Without proof that “safe” structures are mathematically guaranteed to be safe, then it’s just the unsubstantiated claims of Rust’s marketing-team.
Rigorous proof of the memory-safety of a system becomes more difficult as the size and complexity of that system increases. If it isn’t done early, it’s unlikely to be done at all. Rust’s core library is huge (and it’s always growing) so it’s unlikely that the Rust team will ever bother to do this.
This is a problem.
We can broadly categorize memory-management systems into deterministic memory management (C, C++, Rust, etc.) and nondeterministic memory management (Java, Python, Go, etc).
- Improving the memory-safety of nondeterministic memory management systems can be done separately from the code that runs on that system. If Oracle finds a better garbage-collection algorithm, they can swap it out in the next JVM release. You don’t need to modify your code to use it.
- Improving the memory-safety of deterministic memory management systems must include changes to the application code.
C++ smart-pointers aren’t a drop-in replacement for C pointers. You have to go through the system and replace C pointers with smart-pointers, and it’s not always clear which smart-pointer you should use. Worse, changing between smart-pointers can be painful as well. As a result, for any sufficiently large C++ program, any C pointer that existed within the application when smart-pointers were first introduced are likely to remain C-pointers forever.
That’s a lesson we can apply to Rust as well. In the unlikely event that Rust is formally and rigorously proven to be memory-safe, we are likely to find some structures or patterns that violate memory-safety. That means that previously-valid code will become invalid-code that has to be rewritten. Any time you spend rewriting code is time you aren’t spending writing new code.
That’s a risk that a lot of people aren’t going to be willing to take.
C++ doesn’t have to do this. C++ makes no attempts to prove that it’s memory-safe because C++ doesn’t make the claim that it is. If the draw of a language is “like C++ but safer” then you must prove it. As long as that argument remains unproven, it’s not definitive… it’s a conjecture.
Identify when safety constraints are violated in “unsafe” blocks.
It's not enough that we should be able to prove that safe code is "safe". As silly as it sounds, we also should be able to prove that unsafe code doesn't leak memory errors into safe code.
This is already possible in trivial cases, and there is some promising research into this area; but if unsafe blocks of code can contaminate safe code, then I must assume that unsafe code does contaminate safe code. After all, a program is only as safe as its least-safe component. If my code is sound but I have a leaky dependency, then I have a leaky program.
Yes, this would likely impact Rust’s interoperability with C. Rust is just going to have to deal with the fact that interoperability with C undermines the argument that Rust is memory-safe, because any program that uses a C library can only be as memory-safe as that C library.
Provide mature, non-beta libraries for common tasks.
Ada is formally proven as both memory-safe and thread-safe. Writing Ada feels like writing Visual Basic. That Ada isn’t fun to write and doesn’t follow C-like syntax is probably part of why it’s not more popular. However, it proves that being memory-safe simply isn’t enough to become popular. You have to provide value that C++ and Java do not. Or, at the very least, you have to provide a comparable level of value. Right now, Rust doesn’t do that very well for general-users.
Rust is really good for writing command-line applications. There are also some phenomenal web-libraries that make it viable as a high-performance web-platform. This is, in my opinion, one of the places Rust shines. It fits neatly between C++ and Go, in that has a much better web-ecosystem than C++ but it allows more freedom than Go. Among those frameworks, my personal favorite is Actix-Web — but even Actix-Web uses dark-sorcery and memory-safety violations to function. That’s… not ideal.
But I invite you to do a quick experiment.
- If you are using a mouse, double-click any word in this paragraph. You should’ve selected a word.
- Now triple-click it. You should’ve selected that word’s whole paragraph.
This is very basic functionality. The last time I checked, no Rust-based GUI library does this. A lot of Rust libraries are in this kind of “unpolished” state. I’m happy to use some of them in personal projects, but I don’t use any of them in commercial projects because they aren’t ready for prime-time.
Worse, Rust projects have the same problem as Node projects, in that there’s a tendency for them to suddenly evaporate. The Rust ecosystem doesn’t do a good job of capturing commercial markets because the Rust ecosystem as a whole does a poor job of cultivating consumer-trust.
You must also consider that Node.js has a much more robust following than Rust does. Rust and Node are comparable in a lot of ways, and Rust has incorporated a lot of the best parts of Node.js’s ecosystem. But aping Node isn’t enough to become the next C++ — it also needs to have viable and competitive alternatives to C++’s strongest libraries. That no viable Rust GUI library currently exists is a huge (but not insurmountable) problem.
I think it’s possible. In time.
Rust could become a viable alternative to C++ and Java. It’s not going to be something that happens overnight. C++ and Java have been around for decades. They have done a better job of staying relevant than COBOL did, so they aren’t going anywhere. The goal right now probably shouldn’t be “how can we be as popular as C++ and Java”. It’s probably more reasonable to ask “how can we be as successful as Node” or “how can we be as successful as Go”? And the answer is by focusing on specific functionality that a broad audience can appreciate: “what would it take to win over game-designers” or “what still needs to be made before I could write a word-processor?”
Because until I can argue why Rust is a viable pick for those types of projects, I won’t be able to argue that it’s the best pick for them either.