| I just wanna give my perspective since I came from high level languages and pretty much exclusively use Rust now, so perhaps I can articulate why I find value in the language. And my apologies if my input is not wanted, no need to respond if so. First of all I respect your point of view - I'm not a Rust absolutist, I think that garbage collected languages are a massive advantage for a lot of things and would never criticise someone choosing a higher level language. Likewise I wouldn't criticise someone choosing Zig or Oden or Jai or even C for tasks where you really need that low level control. For me, I like to have a single language that I can use for pretty much everything. Afaik there is no other language that is a) popular b) has a modern toolchain with integrated build, formatting & linting etc, and c) can be used both in the kernel and for developing websites. Rust might not be the best choice for most of the spectrum of software, but it's good enough for everything. I can write a low level service + a web server and UI in the same language, where with other choices I would need to use two separate languages. This matters to me because I don't have the time to maintain mastery of multiple languages, I find a lot of value in focusing deeply on one language and learning it completely. Now I also don't write a lot of low level rust, I've never written a block of unsafe before and I probably write "unidiomatic" rust with too much copying, too many Arc<Mutex>>'s etc. But I like knowing that I can if I need to. Rust has a lot of other things going for it. A good type system with plenty of nice language constructs that are missing in a lot of higher level languages. It has Cargo and a healthy ecosystem (although I do worry about the number of dependencies used sometimes). And a large community of very smart people. I'm not saying this is exclusive to Rust, but as a whole Rust is a unique language with no alternatives if you value the things I do. So I would say that it's approach to memory safety threads the needle where it can be used (although not the very best choice) for when you'd use a higher level language, but also gives enough control that you can do plenty of low level stuff in it safely, and with clearly delineated unsafe sections where you really can do anything. |
For low-level programs, I already said that Rust doesn't offer much safety for the things I reach low-level languages for (or, conversely, its safe subset doesn't offer the very control I'm after in such a language). Furthermore, the complexity and implicitness of the language make it harder for me to carefully understand the kind of subtle code I write in such programs. The long build times could mean I write fewer tests.
For high-level programs, Rust's safe subset is technically sufficient, but the problems are even worse (and exactly match C++'s): High level Rust code looks quite good and is easy to write, same as in C++, but the problems start with the maintenance and evolution. Small local changes - to a returned object's lifetime or thread-share ability, or between static and dynamic dispatch - require non-local changes. That's because low-level languages have low abstraction, i.e. the same contract covers fewer possible implementations. True, unlike C++, Rust tells you what things you need to change, but you still need to change them. That was the main problem we had with C++: the code looks great and it's very easy to write at first, but the maintenance and evolution costs - especially when the program is large and long-lived - get high and remain high forever. Furthermore, once a program grows large, it starts suffering from similar performance ovhearheads large C++ programs suffer from: you find yourself needing more dynamic dispatch, which is slow in Rust and C++; you find yourself needing more shared objects with different lifetimes, which are also slow in those languages, so the program isn't even particularly fast or scalable (sure it's faster than a JS or a Go program, but that doesn't say much). Java (or C#) which is aimed at optimising the performance of large programs, removes many of these overheads. Lastly, deep always-on observability/profiling isn't quite poor (it's better now with eBPF, but still a long ways away from what you get with Java or C#).
So yes, Rust and C++ are intended as "one language for everything", and Rust is probably somewhat better than C++, but your high level programs pay for the low level feature (i.e. suffer from the maintenance and performance costs of low-level languages), while your low-level programs pay for the high-level features (the complexity needed for implicitness and safety). So yes, you can do everything, but rarely as well as could be done, and while I see the value in getting expertise only in one language, 1. it's a language that requires a lot of expertise as its "multi-functionality" makes it very complicated, so much so that you could probably become an expert at two more specialised languages for not much more effort, and 2. I think that if you really need to write low-level code, e.g. you're writing a kernel or a hardware driver or a controller or a GC, then expertise in the domain dwarfs expertise in the language anyway (i.e. we're talking years of required experience until you're really good at it).
BUT I acknowledge that the weight I assign to these things is subjective, and I'm certain others reach the opposite conclusion through arguments that are no less reasonable than mine.