| Thank you for the thoughtful response! A few thoughts: > You can't bypass borrow checker, and you wouldn't do everything in unsafe. Isn't unsafe still bypassing the borrow checker, in the sense that you're mostly using it because you're doing something the borrow checker does not otherwise allow? > Because Bevy knows when and how Resources are related it systems can freely run in parallel if two resources are unrelated and mutable, or related and immutable. But again, I don't understand how that is a unique benefit of Rust. It's completely possible to implement something in C which allows multiple threads to run over unrelated memory locations, or the same immutable memory location. As a programmer you have more options for how to achieve this when not restricted by the borrow checker. Most of the ECS systems in existence solve exactly this problem, and probably most of them are implemented in C++. > Point of a good programming languagues isn't to enable writting programs that can do anything but to aid programmers in writing error-free programs. I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language. It's probably a priority of most languages, but there's no reason it has to take the number one spot. I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program. Rust's thesis is that memory safety issues are such an obstacle to delivering user value that the language should prioritize safety at the expense of a certain amount of pain for the programmer. Languages like Zig and Jai prioritize programmer velocity and relegate safety to optional static analysis tools. Python is another example: it's very easy to write an incorrect Python program, but the barrier to entry is so low that it enables non-programmers like scientists to do very interesting things by copying a few lines off the internet into a notebook. There's no one best set of tradeoffs. But as I said from the beginning, if one of the main tasks you are doing is manual memory management, as domains like game dev and HPC require a lot of, you might want to choose a language which prioritizes explicit memory management. |
Not really. But using raw pointers and converting to/from memory addresses isn't something borrow checker can check.
It's a borrow checker not address verifier.
E.g. you can take raw pointer, and set two mutable variables to point to it and borrow checker can't know they point to same address.
> But again, I don't understand how that is a unique benefit of Rust.
It's statically enforced by the compiler using Rust's type system.
As far as I know Zig can't say well these two functions can run in parallel because they are at compile time guaranteed to never access same resources and it's impossible to bypass it (outside unsafe). And their content is thread-safe based on the type they satisfy.
> I mean, I think it can't be taken for granted that preventing errors should be the top priority of every programming language.
Douglas Crockford made a good case that every language should on some level try to prevent errors.
> Python is another example: it's very easy to write an incorrect Python program
Python is also older than Java, but even Python is memory safe (GC). Zig and new batch of better C aren't. In that way we definitely regressed.
> I would argue the universal priority of programming languages is to enable the programmer to deliver user value through their program.
If that is truly the case we'd be all programming in Excel and Access. Anything can deliver value, question is - can it be maintained, and at what cost.
In lieu of that a language that makes a set of errors nigh impossible is better than a fast one where those errors are trivial to cause.