I've worked with debian maintainers and they are some of the best C programmers around, and even they would use Python as much as possible, using C for the lower level stuff.
I really believe this is where Rust will - and maybe even should - live. I do not believe it will replace C and Python in this example, but definitely C for those wishing to have another tool to use, and Python for some as well.
First it was C++, then it was Java, now it's rust.
Perhaps it would be easier to fire WG14 for incompetence[1], add a few things to the language, and update the standard library.
[1] These guys haven't been able to come up with a non broken version of strcpy with 40 years of trying.
I have never stopped "thinking in C" from my few years of embedded work near the operating system or on bare metal. It's the language that makes the most sense when you study CPUs. The concepts match OS apis. It is simple to write C glue for any of the above languages. C libraries are not mangled. Etc etc. C feels like the language that computers and software are made with, and all other languages just try to hide that by building someone on top of it. I say that as a feeling but it might just be true.
Now Rust is here and I love it when it tries to be like C. It's clean, pure, I believe the compiler when it says something (not like Cpp), and the mental leap to the borrow checked matches ownership dynamics from C pretty well.
I hate it when it tries to be like Python or JavaScript, pulling 1000 libraries for something flashy and simple. But that's us, the programmers. The language is strict because it's the core of C without the generality. If C is the wilderness, Rust is the national park. It's beautiful, sparse, you can get lost for days, but it's safer.
You won't get rid of C until UNIX/POSIX goes away, that is why C is still around mostly.
Now i fully agree with WG14's incompetence, it is impossible to understand that in 40 years, it was so hard to add proper string and array types to the language, between new native types, additional struct based standard library functions, or fat pointers, one approach would definitly have worked out, if they bothered.
strcpy() is there for historic reasons, and is staying for compatibility. Functions like strtok() and in fact most functions in <string.h> are awful -- don't use them for new code.
In the same way, zero-terminated strings are there for historic reasons. They weren't a C invention. And they are staying for compatibility. There's no practical way to get rid of them.
I don't think that it would be useful to add another string type to the C library. The types of programming where C is useful today, you need memcpy and snprintf, that's about it. To add another standardized string type would only lead to a situation where we now have 15 incompatible solutions, and none of them are good for everyone.
Built in string types are more useful for languages with some form of automated resource management where one is used to mindlessly concatenating and splitting strings. The types of programming where that's a valid approach, don't use C in the first place. It's a bad fit.
Btw. zero-terminators are not entirely bad. They are an in-band signal (and can be easily completed using an additional out-of-band signal). And that can be quite useful, for example when looking at a plain binary. The space saving part that comes with zero terminators for small text strings is another thing, but admittedly has become irrelevant.
Not the only examples, there are plenty of other systems following similar approaches.
This is not an onboarding problem. This is a trait of the programming language, which only gets worse as a project grows.
It's high time for the Rust community to start to get honest with themselves and stop pretending problems don't exist. It's already bad enough with the clusterfuck which is async Rust, and you're doing no one any favor to pretend that the borrow checker doesn't add a heavy cognitive load.
Actually being forced to think about how long allocations and resources need to live turned random "takes days to figure out" bugs into an instant response of "oh, that was stupid of me to try doing that huh? Guess I'll try something else"
The borrow checker actively reduces cognitive load once you learn to adopt program designs that mesh well with its requirements. And those happen to be really good program designs across a wide range of axes.
The borrow checker means I have to pay less attention to memory management, not more. That’s why it exists. So I don’t have to worry about it. It catches my mistakes, I fix the code, I move on.
For example, dealing with multi-threading and low-level memory management without the assistance of thread-safe types and borrow checker adds mental overhead of verifying and upholding all the requirements manually.
Rust is for high performance, high concurrency applications where the developer can spend all day building them.
By whom exactly? I think it's actually the exact opposite. It completely frees you from having to think about entire classes of bugs.
You didn't read the article, didn't you?
In practice it is absolutely the opposite. Rust makes really challenging problems extremely tractable, and takes an enormous amount of mental overhead off the table.