Discipline Doesn’t Scale
Over a decade ago I used to argue this with the C++ committee people. Back then, they were not concerned about memory safety; they were off trying to do too much with templates. The C++ people didn't get serious about safety until Rust came along and started looking like a threat. Now they're trying to kludge Rust features into C++ by papering over the unsafe stuff with templates, with some success. But the rot underneath always comes through the wallpaper. Too many things still need raw pointers as input.The encouraging thing today is that we're kind of converging on good practices in language design.- You really want to declare types for function parameters. The compiler needs that information for checking, and the programmer, and the maintenance programmers who follow behind, need that information so they know how to call the thing.  On the other hand, you can usually infer the result types of expressions by a simple forward process. So C++ gained "auto", Rust and Go started off with that arrangement, Javascript got TypeScript, and Python is getting there via a side trip through unchecked type declarations.- The three big questions in C: "How big is it?", "Who can delete it?", and "What locks it?" C gives no help with any of those. C++ now tries to address the first two. All the garbage-collected languages address the first two. Rust addresses all three.- The idea that locks should be connected by syntax with the data they are locking took far too long to become accepted. Partly because the Ada rendezvous and the Java synchronized object didn't work well. Even Go doesn't do that very well. But language design seems to be coming around. When and if thread-type concurrency comes to Javascript, the webcrap crowd will create race conditions everywhere without automation in locking.