3 ms·
> You have to memorize the borrow checker Correct me if I am wrong, but Rust at least has a borrow checker while in C (and Zig) one has to do the borrow checki
by codedokode 2y ago
> You have to memorize the borrow checker
Correct me if I am wrong, but Rust at least has a borrow checker while in C (and Zig) one has to do the borrow checking in their head. If you read a documentation for C libraries, some of them mention things like "caller must free this memory" and others don't specify anything and you have to go to the source code to find out who is responsible for freeing the memory.
- nyrikki 2y agoRust gives two reasons for the borrow checker, iterator invalidation and use after free. As I have always bought into Dennis Ritchie's loop programming concepts, iterator invalidating hasn't been a problem. Zig has defer which makes it trivial to place next to allocation, and it is released when it goes out of scope. As building a linked list, dealing with bit fields, ARM peripherals, etc...; all require disabling the Rust borrow checker rules, you don't benefit at all from them in those cases IMHO. It is horses for courses, and the Rust project admits they chose a very specific horse. C is what it is, and people who did assembly on a PDP7 probably know where a lot of that is from. I personally prefer zig to c... but I will use c when it makes the task easier.
- int_19h 2y agoThe point is that any formal borrow checking will reject perfectly valid patterns because they are impossible to statically prove, and this comes up especially often with data structures like graphs. So you end up struggling against the compiler - either you just go unsafe (in which case you have to be even more careful than in C and Zig because Rust makes more optimization assumptions based on ownership which you're now responsible for), or else you use hacks like using indices instead of pointers to, basically, work around the borrow checker.
- codedokode 2y agoYou are describing the deficiencies of Rust implementation of a borrow checker and disregarding general benefits of it. Obviously there could be some way to mark self-referencing objects. C/Zig do not even allow to specify who is responsible for freeing the allocation, and every time you use a library you need to either search the docs or (more often) reverse-engineer the code. Probably this is why writing or checking C code is so slow. I end up adding annotations to function prototypes but nobody is going to validate them so they only serve as documentation.
- int_19h 2y agoWell, we are comparing real world languages, so of course I'm going to talk about the limitations of the actual checker that Rust has. That said, is there a better (as in fewer false positives without giving up safety) implementation of lifetime tracking out there? I mean, fundamentally, the problem is that the question ultimately boils down to telling what the code will do without running it. C and Zig have exactly the same facility to let you specify who's responsible for allocation - owning vs non-owning types for resources; it's just that you have to write them by hand, and for types that are owning, destructor calls must be done explicitly (but still, the pattern of "if I got an instance of OwnedFoo, I need to call destroy() on it" is much more straightforward then chasing the docs for each function).