Sadly, Rust is only a "huge leap forward from C and C++" for some use-cases.
Simple things like returning a const reference to a slot in an immutable array are easily 10x the amount of source code in Rust when compared to C. And all the standard libraries for embedded systems are C, so to get into embedded development, you definitely need to be good at reading C code. Rust is an additional skill, but if you only know Rust and no C, you're of no use in embedded land.
I think that's the main reason why we don't move away from C: You still need a firm grasp of C if you want to be a capable higher-level developer.
C++ is then the logical upgrade because it's compatible with C and looks very similar. Java also did OK because it looks and feels very similar. And there's good automated C to Java converters. So you get the benefits of Java over C almost for free. Rust, on the other hand, throws away most of the C conventions and that makes it feel foreign and "incompatible".
Rust also suffers from a serious "not invented here" problem, in my opinion. It's super easy to re-use C code in C++ or Java. It's significantly more difficult to re-use C in Rust unless you go unsafe and abandon most of the Rust advantages. That means most dependencies need to be re-implemented in Rust if you want to have all the advantages that Rust offers. Go had the same problem, but they had Google's weight behind them to push out tons of libraries. Who is doing that for Rust?
In the end, I agree with the article: Rust is great! when it fits. But there are still plenty of situations left where Rust is worse than old-school C.
> Rust also suffers from a serious "not invented here" problem, in my opinion. It's super easy to re-use C code in C++ or Java. It's significantly more difficult to re-use C in Rust ...
It feels like a mischaracterization of Rust and I strongly disagree. Both the language and tooling are designed from the beginning for interop with C code. It isn't very hard to do if you have tried it.
> ... unless you go unsafe and abandon most of the Rust advantages. That means most dependencies need to be re-implemented in Rust if you want to have all the advantages that Rust offers.
This 'Rust is useless if you use unsafe' is a stance that is well debunked, but still gets repeated like this. Ensuring safety using Rust semantics across an FFI with a language like C is impossible - making unsafe necessary. But just because you use unsafe doesn't mean that the language lost most of its advantages. In fact, almost every Rust program uses unsafe code, if you care to look at the code in the standard library. Yet, that never seems to be a problem.
What unsafe does is to cordon off a small code area where certain invariants have to be asserted manually, instead of relying on the borrow checker. You still get the safety for the rest of the code. In case you do get safety violations, there is much less code to debug. This is a significant advantage over languages like C++, considering that unsafe blocks are usually less than 5% of the code, even in the worst case. But to take it further, C libraries often have corresponding Rust wrapper libraries that create safe wrappers over C FFI calls. In addition to the small unsafe blocks to verify manually, these wrappers have the additional advantage of being widely used and debugged by a wider community. There are innumerable such wrappers on crates.io and it's uncharitable to accuse the language of NIH syndrome.
My attempt at OpenGL rendering with Rust turned out to be a lengthy journey of suffering through way too many layers of rust wrappers around unsafe C shared libraries. I especially hated that I constantly had to use casting helper functions to go from pre-defined OpenGL constants back to their associated integer values.
And I do think it's valid to accuse NIH syndrome if there is exactly 1 OpenGL API in C but there are 100+ Rust crates for various OpenGL wrappers.
> My attempt at OpenGL rendering with Rust turned out to be a lengthy journey of suffering through way too many layers of rust wrappers around unsafe C shared libraries. I especially hated that I constantly had to use casting helper functions to go from pre-defined OpenGL constants back to their associated integer values.
From this description, I can't figure out if you used FFI or a wrapper library. But it looks like you are complaining about both - which can't happen together. And the problems you mention seems very specific to the choices you made. I have faced similar problems with other code - something often solved by choosing a different library or approach. I don't see that affecting Rust's FFI story.
> And I do think it's valid to accuse NIH syndrome if there is exactly 1 OpenGL API in C but there are 100+ Rust crates for various OpenGL wrappers.
By definition, they didn't invent anything if the crates were wrappers. They were just using that exactly 1 OpenGL API - the thing that you were accusing them of not doing. And as for 100+ Rust crates, I don't think that should be a problem. Wrapper developers often try different API styles. It's just that crates.io makes them all very visible. In practice, just one crate (or a group of related crates) become popular enough to be the defacto standard in a segment.
It's not, and you're over indexing on your experience with OpenGL.
There are plenty of rust libs that are thing wrappers over C libraries. They're widely used, without a problem. libgit2, written in C, is the most popular Rust library for git bindings.
Despite that, people do prefer pure Rust libraries for a very valid reason - it makes building the project, especially cross-compiling very easy. That's why cargo audit shifted from libgit2 to gitoxide.
Who is sponsoring the development of these libraries? The Rust Foundation gave the developer of gitoxide grants to develop it, with the eventual goal of replacing libgit2 in cargo.
I'm sorry you had a bad experience with OpenGL, but I don't think it's accurate to extrapolate your experience with that onto the entire ecosystem.
Simple things like returning a const reference to a slot in an immutable array are easily 10x the amount of source code in Rust when compared to C. And all the standard libraries for embedded systems are C, so to get into embedded development, you definitely need to be good at reading C code. Rust is an additional skill, but if you only know Rust and no C, you're of no use in embedded land.
I think that's the main reason why we don't move away from C: You still need a firm grasp of C if you want to be a capable higher-level developer.
C++ is then the logical upgrade because it's compatible with C and looks very similar. Java also did OK because it looks and feels very similar. And there's good automated C to Java converters. So you get the benefits of Java over C almost for free. Rust, on the other hand, throws away most of the C conventions and that makes it feel foreign and "incompatible".
Rust also suffers from a serious "not invented here" problem, in my opinion. It's super easy to re-use C code in C++ or Java. It's significantly more difficult to re-use C in Rust unless you go unsafe and abandon most of the Rust advantages. That means most dependencies need to be re-implemented in Rust if you want to have all the advantages that Rust offers. Go had the same problem, but they had Google's weight behind them to push out tons of libraries. Who is doing that for Rust?
In the end, I agree with the article: Rust is great! when it fits. But there are still plenty of situations left where Rust is worse than old-school C.