5 ms·
it's not just about multi-threading, it's also about actually dealing with memory in a way that's safe in a single thread as well without introducing GC, which
by jolux 6y ago
it's not just about multi-threading, it's also about actually dealing with memory in a way that's safe in a single thread as well without introducing GC, which we know from C is hard too
- bcrosby95 6y agoIn my experience most of the painful difficulties people have with the borrow checker is because it works like a read-write lock. AFAIK this aspect isn't required to have safe single threaded code without a GC.
- bitwize 6y agoIt is if you want to have automatic deallocation with a strict guarantee of memory safety including no use-after-free bugs.
- bcrosby95 6y agoHow does this relate to whether or not you plan to mutate things? Wouldn't plain ole counting work for this, regardless of whether or not they're mutable, rather than what Rust does - allowing multiple readers and no writers, or zero readers and 1 writer?
- erik_seaberg 6y agoRefcounting is GC; it automatically detects at runtime that an object has no references. It also adds a substantial cost that Rust is trying to avoid, often by copying immutable objects (which have better cache locality than random access to refcounts everywhere).
- bcrosby95 6y agoI'm not talking about GC. I'm talking about Rust references: https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html https://doc.rust-lang.org/book/ch04-02-references-and-borrow... > At any given time, you can have either one mutable reference or any number of immutable references.
- erik_seaberg 6y agoOh, I get it, you're suggesting all references could be mutable, but still limited to the lifetime of the object. I guess the downside would be that you can't design an API like iterator invalidation that relies on "some (mutable) methods can't be called while any other (immutable) references exist".
- comex 6y agoIt would mean that, once you obtain a derived pointer – say, if you start with a Vec<Foo>, a pointer to Foo that refers to the first element – you would have to throw away that pointer as soon as you made any function call whatsoever. After all, that function call might mutate the Vec<Foo> and cause the backing storage to be reallocated. In practice, this is unworkable enough that it would basically forces you to reference count the Foo, so you could preserve pointers across calls by incrementing the reference count. On the other hand, Rust's approach is suboptimal in cases where you're using reference counting anyway, or are willing to pay the cost of reference counting.
- steveklabnik 6y agohttps://manishearth.github.io/blog/2015/05/17/the-problem-with-shared-mutability/ https://manishearth.github.io/blog/2015/05/17/the-problem-wi...
- boustrophedon 6y agoThe immutable borrows also help prevent iterator invalidation in single threaded code when using an iterator.
- jolux 6y agoYes, exactly. One of my first big fights with the borrow checker was over not realizing I was invalidating an iterator by mutating it by looping over it. Then it clicked for me.