5 ms·
Borrow checking and immutability solve two different problems. Immutability is about the absence of ownership and state, while borrow checking is a way to manag
by stingraycharles 7y ago
Borrow checking and immutability solve two different problems. Immutability is about the absence of ownership and state, while borrow checking is a way to manage ownership.
One does not replace the other, they coexist solving different problems.
- louthy 7y agoExactly, it's like the integer 5, nobody owns the number 5, nothing borrows the number 5, it just exists as a value that anything can use (and trust to always be the same). When immutable values (whether it's the number 5 or a record, or whatever) are used with a pure function then the returned value can be essentially a direct replacement for the function invocation, making the operation essentially take zero time (i.e. there aren't intermediate mutation states, locks, or any other coordination). This is the point that Rich Hickey suggests in a number of his talks [1] - which are always excellent IMHO. [1] Are We There Yet - https://www.youtube.com/watch?v=E4RarTAZ2AY https://www.youtube.com/watch?v=E4RarTAZ2AY
- stuhood 7y ago> When immutable values (whether it's the number 5 or a record, or whatever) are used with a pure function then the returned value can be essentially a direct replacement for the function invocation, making the operation essentially take zero time (i.e. there aren't intermediate mutation states, locks, or any other coordination). The same can be said of any variable in Rust that is passed to a function via immutable reference. Borrow checking guarantees (at compile time, with no runtime overhead) that even if a user passes something that supports mutation (such as a BTree or an array) to a function, that that function may not mutate unless it has permission to. This means that if you have an immutable reference to something, it can be treated as a value. For example: a Vec or BTreeMap (structures that supports mutation) can safely and easily be used as Map keys in Rust, because borrow checking guarantees that once the Map has taken ownership of the structure, it "is a value": ie, is immutable.
- 0815test 7y ago> The same can be said of any variable in Rust that is passed to a function via immutable reference... I don't think this is correct. Rust does not really have immutable references, it has shared references vs. exclusive ones. Shared references are ordinarily immutable, but controlled mutability can be reintroduced (directly or indirectly) via a variety of type constructors (Cell<>, RefCell<>, Mutex<> etc.). Hence something that is borrowed immutably cannot be assumed not to change in the general case-- unless one also takes care to work with these mutability mechanisms as needed, which cannot really be done in a "fully general" way. Rust developers seem to have realized that actual immutability is not that easy, and that the guarantees that they do offer may be more appropriate.
- deleted 7y ago[deleted]
- stuhood 7y agoBorrow checking allows even structures that support mutation to be safely (checked by the compiler) treated as immutable, and thus as values. Clojure also recognizes the connection between ownership and mutability in its "transients": https://clojure.org/reference/transients https://clojure.org/reference/transients ... compile time borrow checking extends that idea to an entire language.
- casion 7y agoWhat do transients have to do with ownership? They are simply a way to gain new performance characteristics from an existing data structure.
- stuhood 7y agoThe thing that makes it safe to use mutation in the context of a transient is that you can know with certainty that you have exclusive access to the value (because no other viewer has observed it yet). This is also what borrow checking can guarantee: except in significantly more positions in the code, and at compile time rather than runtime.
- truth_seeker 7y agoNice explanation
- namelosw 7y agoNot totally different, with strict immutability enforced for the whole language there's no need for borrow checking. Because there's no identity at all. You don't have to borrow number 3 because another number 3 is the same 3 as any other 3.
- wilsonthewhale 7y agoYup, this is the reason why both Rust and Clojure are my favorite languages. The same problem (concurrency), with solutions pretty much on opposite ends of the spectrum. One with pervasive immutability and the other with static checking.
- andreareina 7y agoOne of the reasons that immutability gets pushed is that it solves concurrency's shared mutable state problem, which is exactly the same problem that borrow checking is meant to solve.