TBH, I think some of their detailed explanations are unnecessary, depending on the intended audience. I'm thinking of chapter 4 in particular, which I just reviewed (for the official Book and the Brown book). It heavily overemphasizes the "stack vs. heap" perspective, making it seem like Copy
is a "stack data" property and like borrow checking is solely concerned with dangling (heap) pointers and the like.
(The Copy
conversation came up in another topic with the OP a couple weeks ago.)
If one understands when local variables drop and that owners like Vec<T>
drop what they own recursively, I think a lot of the details on the level of "here's how the call stack and global allocator work" could be replaced with a higher-level "got destructed and cleaned up resources" presentation. This would also have the benefit of getting away from saying "free heap memory" as if it was the only ownership and resource management concern, "popped off the stack" as if it was the only time a destructor ran, etc.
It could be an interesting exercise to rewrite the chapter to eliminate a lot of the low-level details and mix in non-heap examples (like say File
).
It is my suspicion that a lot of this material, and similar other learning material, was written by people with a C/C++ background. There are a lot of examples that amount to "If you wrote this in C, you might do this, but oops see how that leads to a UAF or w/e. That's why Rust's borrow checking is great!" But if your audience doesn't have a C background with all the knowledge and background that entails, the examples are far less effective. You wouldn't necessarily think about the problem from the same perspective at all.
The Brown Book does this repeatedly with exercises like "Imagine this compiled. Is there undefined behavior? If so why?". But then they only consider certain types of undefined behavior! You, the reader, have to read the instructor's mind and infer what point they were trying to make (usually something about reallocation double frees, etc).
First of all: That's not only misleading, it's dangerous, as it gives the impression that if you could reason enough to avoid allocator related problems / write it correctly in C, you could sidestep the borrow checker with unsafe
and have a sound program. But aliasing &mut _
are automatic UB, as is writing through a &_
without an UnsafeCell
. And these show up in answers to their quizes which they claim are not UB.
But second of all, if the reader doesn't have a C background, it's going to be challenging to make all the same assumptions implicit in those questions. It's almost like you have to learn a subset of C in order to make sense of the material that's supposed to be teaching you Rust.
Given that the Book is not intended to be "Rust for C Programmers", I think it would benefit from some rewriting to present things in a more general or higher-level way. And a more accurate, Rust-specific way! For example, if you internalize "aliasing a &mut _
is UB", a lot of the low-level details become somewhat moot. (How that helps ensure memory safety is great for understanding the motivation, and should still be pointed out, but memory safety need not take the center stage everywhere while we pretend other considerations and other types of UB don't exist.)