> but the advantage of letting the programmer fully control every knob in the chain is immense.
That's actually not completely true.
Take the restrict keyword for instance. Super painful to use in C/C++ and very dangerous. In Rust since the language has constrains around single mutable pointers they can turn it on globally and you get it "for free". If I recall correctly it's going live in one of the upcoming stable releases.
Sometimes constraints can actually let you get better performance than a wild-west of pointers everywhere.
> going live in one of the upcoming stable releases
If I remember correctly, it was originally enabled but had to be disabled because LLVM had some bugs around how it was handled. These arose because `restrict` is comparatively rarely used in C / C++ code.
Of all the sharp tools in C, restrict is one of the last things I'd call dangerous (restrict is not a standard keyword in C++, by the way, although most compilers support it as an extension). It's completely opt-in, relatively rarely used, and to even think of using it you have to be already thinking about aliasing issues. If you write a function using restrict and suddenly completely change your intent mid way, I really don't think that's a language design issue. Of course it's still a sharp tool and explicitly meant as such - as a last resort for cases where you can't rely on the compiler to infer the right thing on its own.
Sure but my point wasn't about the ergonomics of restrict, more that having a wild-west of pointers means that some performance optimizations are now off the table vs languages that are a bit more constrained in how they approach data access patterns.
They're not off the table, but you do have a point in that they are harder to attain reliably (hence the popularity of Fortran in certain circles). That being said, I don't believe there's any optimization that Fortran (or any other general purpose AOT-compiled language) can do that, for instance, C99 couldn't. That's why restrict exists.
There are two caveats to that statement. The first is JIT compilation, for obvious reasons. The second is that some domain specific languages with very restrictive semantics could do memory layout optimizations that are off the table by definition in any general purpose language (transform AoS patterns to SoA, etc.).
That's actually not completely true.
Take the restrict keyword for instance. Super painful to use in C/C++ and very dangerous. In Rust since the language has constrains around single mutable pointers they can turn it on globally and you get it "for free". If I recall correctly it's going live in one of the upcoming stable releases.
Sometimes constraints can actually let you get better performance than a wild-west of pointers everywhere.