Are new devs less likely to screw things up in Rust? Probably. Is a modern Rust codebase easier to onboard with than a 40 year old monstrosity of a Microsoft C++ codebase? You bet! Are more people excited about learning Rust? Probably. Is rust much faster to learn than C++? Call me a skeptic.
I've written Rust professionally and would rather write Rust than C++. That said, almost every concept you need to understand C++ is also needed to understand Rust, but then Rust adds additional complex semantics that aren't going to be intuitive to novices and don't trivially map to either other common high-level languages or obvious low-level concepts.
> That said, almost every concept you need to understand C++ is also needed to understand Rust
I agree that many basic C++ concepts are also present in Rust, but C++ is more than just its basic concepts: it's a huge set of features on top of those that interact with each other in complicated ways. Like how constructors aren't functions but something very special. If you just want to be a beginner C++ dev who works alone on their piece of software that doesn't have any dependencies, you can be fine, you just use the subset you are familiar with. But if you want to maintain other people's code, you need to fully understand what it is doing, the C++ features it's using. Rust's whole feature surface is absolutely smaller than that of C++, and the features that exist integrate way better than the C++ features.
Plus, if there is a gap or misconception in your knowledge, in Rust you would get a compiler error, often very well explained. In C++ you would get a segfault, often not a really nice one.
Rust's "feature surface area" reaches or exceeds that of C++ through procedural macros, which surfaces the entire Rust AST to the developer. Major Rust crates like serde use this feature, and when it goes wrong the errors are actively misleading. I've personaly been bitten by this, it's incredibly frustrating to debug. https://serde.rs/derive.html#troubleshooting
I agree that debugging bad macros is annoying, especially proc-macros but that’s not comparable since by their very nature proc macros are no more powerful than hand written code. They cannot create new semantics, at best they can add new syntax sugar for things that already exist in the language.
proc macros are their own walled off thing with well defined input of tokens, and well defined output (also of tokens). You have tooling to inspect their output (cargo expand). Compare this to the average C++ feature which is usually implicit and not visible in syntax and interacts with other C++ features in interesting ways that you have to keep in mind.
Well, our C++ codebase has a lot of threads that talk a lot, and buffers we'd rather not copy. Plus ad-hoc NIH versions of stuff that exists in Rust's stdlib, like mpsc, or ad-hoc NIH versions of popular crates, like for logging.
I sometimes just wish I could punt to Tokio. Why am I managing threads? Threads are an implementation detail!
I see it as, Rust tells you about the complexity and helps you with it. C++ waits until you trip on it, and then tells you to use Valgrind.
I could be wrong, though. Or I could be 5 years too early.
I think that the C++ version of Tokio is ASIO (either its boost or standalone variant). Neither is in the standard library. 20 Years ago it would have been ACE.
I think you DO have to know about those, or close analogs, in writing Rust. I like both C++ and Rust but I will rise to defend C++.
1. Exception safety becomes "catch_unwind." You might object that nobody cares about that, but major C++ codebases (Google, LLVM, Mozilla) don't care about exceptions; they are built with -fno-exceptions.
2. Move semantics in C++ are annoying, and so is the borrow checker. In Rust you get hit by things like "this code is fine here, but you aren't allowed to refactor it into a function" because there's no interprocedrural visibility into struct fields.
3. Meta-template higgery-jiggery is real and bad in C++, but has a mirror in Rust. With C++ duck-typed generics you write dumb code that does the thing, and then you can refine it with hilariously awful techniques like SFINAE. In Rust you're googling higher-ranked trait bounds before you can even write the thing. What does `for` do again? I think "strongly-typed language, duck-typed generics" is a bit of a sweet spot and C++ has lucked its way into it.
4. "30 years of cruft" means things like "I speak C preprocessor" which is practical. C compat is why C++ is both so awkward and so successful. There's no smooth ramp from C++ to Rust, the way there was from C to C++; that's a choice and maybe the right choice but it has a price.
"Hilariously awful" template metaprogramming is a thing of the past. It has been years since it seemed needed, or since I read any. New, more intuitive features have displaced it.
With concepts in C++20, you get to choose whether templates are duck-typed.
You don't need to know about about 6 different string types, arcane borrow checker workarounds, RefCell complexity, massive async cruft - acquired by Rust in just 2 years.
C++ will still be used heavily when Rust is buried 6 feet under and HN moves to the next hype language.
> You don't need to know about about 6 different string types
Eh, all these "different string" are different because... Well, they have different requirements. Path is not a normal string, it has platform-dependent implications, String/str are UTF8 strings, the byte-esque string have raw bytes, etc. I know I'm being brief, but I hope the differences I'm trying to illustrate are clear, and why it makes sense for these to be different types.
> arcane borrow checker workarounds
You often end up with these in portable/cross-platform C++ or in performance sensitive C++ code. Also, if you've not burdened yourself with OOP-style thinking and adjust your expectations to the fact you're not writing C++ anymore, but a different language, you'll have an easier time learning Rust. All that said, what you call workarounds is probably idiomatic to Rust developers. And even in the most pathological case of workarounds, the resulting Rust code will be much more succinct than any back-breaking efforts to make C++ readable/correct/performant (two of which you get for free in Rust; sans some complicated domains). Like, as examples: just working with std::variant is a nightmare and requires grotesque constructs with visitors patterns (and often lambdas), std::option is a joke that's marginally better than a raw pointer, etc.
> RefCell complexity,
It's no worse than just working with borrowing, and it's not that often you'd use this anyways.
> massive async cruft
Yes, you have a point here, and everyone's aware of this. And people who have ideas in the community about how it can be addressed can easily participate in the discussion and design process if they desire. Whereas C++ is designed by a committee of people who only barely still use the language in the real world (I know there's exceptions, but alas).
Also, if we got tooth for tooth, C++ has an abundance of more complexity than Rust does, and a lot of it isn't even obviously (hence can be dangerous, or just ruin your day/productivity)
have fun living your life pretending all strings are of the same type. spoiler alert: it's the wrong kind of fun. it's a bit easier if you're from a native English speaking country, but only until you get blown up by utf-8 (if you're lucky) in production.
It might be acceptable in higher level languages where some things will simply break in corner cases, at which point the developer will just say 'don't do that' and all is fine. If you're aiming at a true low-level bare-metal-capable syscall-winapi-native-speaker language, this is not an option.
It’s weird and confusing, but also performant. Remember Rust is first and foremost a systems language. You can get a 10x speed boost by using the right string (str vs string) in certain circumstances.
There are no 20 year old Rust codebase to compare with. C++ has gotten easier and cleaner on the last 20 years, whereas Rust has gotten more complicated. If we want to plot future trajectories...
Unlike C++, the Rust compiler actually helps you when you encounter those complex concepts, first by refusing to compile in tricky situations, and then by providing helpful suggestions.
I've written Rust professionally and would rather write Rust than C++. That said, almost every concept you need to understand C++ is also needed to understand Rust, but then Rust adds additional complex semantics that aren't going to be intuitive to novices and don't trivially map to either other common high-level languages or obvious low-level concepts.