3 ms·
`&T` does not mean it's immutable. It means it's borrowed. `&mut T` means it's borrowed mutably `T` and `mut T` have the same logic but for owned variables. I d
by sakex 4y ago
`&T` does not mean it's immutable. It means it's borrowed. `&mut T` means it's borrowed mutably `T` and `mut T` have the same logic but for owned variables. I don't get the issue there.
- JohnFen 4y agoWait... as a Rust newbie, you bring up a point I could use clarification on. I get that "&mut T" means it's borrowed mutably, but doesn't that automatically mean that "&T" means it's borrowed immutably?
- burntsushi 4y agoTo a first approximation, yes. To a second approximation, "&T" is a shared borrow and "&mut T" is an exclusive borrow. The key point to bring up in the rephrasing here is that "&T" doesn't imply you can't mutate something. Why? Because interior mutability (for example, RefCell and Cell, but always underpinned by UnsafeCell) permits mutation through "&T". RefCell, for example, can be thought of as "borrow checker, but at runtime." In the days of yore, an event called the "mutpocalypse" occurred where by (pre Rust 1.0) there was a huge discussion about potentially changing "&mut T" to "&only T" or "&uniq T" because the more precise model was one of sharing vs exclusivity, rather than immutability vs mutability. The immutability vs mutability model is still useful, it's just wrong in more circumstances. However, it does have the benefit of (IMO) being more accessible by describing borrows in terms of the most common effect: to mutate or not. I don't know which choice would have been the right one, but I am at peace with it. "Rust Atomics and Locks" by Mara Bos has a great discussion of these points toward the beginning of her book, and specifically grounds the choice of which terminology to use in concrete and practical terms, which I really appreciated.
- JohnFen 4y agoHmm, OK. I think I follow this. So, "&mut T" is a bit of a misnomer, then? I can roll with remembering that.
- burntsushi 4y agoDepends. "&mut T" does give you mutability. It just also gives you something else too: exclusivity. So the fact that it gives you mutability is not wrong. It's just incomplete. If something is a misnomer here, I'd probably say pronouncing "&T" as "immutable reference" is it. But it really is not entirely wrong either. I can craft a Rust API that only exposes a "&T" and I can make it so you cannot mutate it. Or I can make it so it looks like you aren't mutating anything, but under the covers, mutation is happening. Take "Regex" for example. All of its methods take "&self." From the perspective of users of that API, thinking of "Regex" as immutable is absolutely the correct model. You, as a user, cannot do anything to that "Regex" to mutate it directly in a way that you can observe via the API. You can't swap out its internal NFA. You can't change its capture group names. You can't change the prefilters it uses. You can't do anything other than use APIs that purportedly tell you "nothing is changing." Under the covers, stuff is definitely changing. The regex engines need mutable space to operate. But all of that is hidden from you, and there's no way to observe those mutations from the public API. (You can technically make observations in the most strictest sense and make an inference from them that things are being mutated internally. For example, by measuring how long it takes for certain regexes to execute. The first search might be measurably slower than the second. But this is clearly not something that is an API guarantee or is something you can directly observe through the API of the regex. I only mention it for completeness, and because this is the Internet.) With all that said, in my mind's eye, when I see "&T" do I think "immutable"? No. My internal conception of it is "shared."
- JohnFen 4y agoThank you for this. This helps. > So the fact that it gives you mutability is not wrong. It's just incomplete. I understand. It means nothing to anybody outside my head, but if I think of "&mut" as a misnomer, that will help me to remember that it's not telling me the whole story. I think the hardest part of learning any language is those little bits that are "hidden" by the syntax, so I need to find where to hang the lampshades so I remember them.
- Measter 4y agoIn addition to what BurntSushi said, it's worth thinking of the interaction as `&mut T` allows unsynchronized mutation. Because it's guaranteed to be unique, nothing else in the program can access the data behind the reference, so you don't need any synchronization to prevent data races. With a `&T` on the other hand, the entire point is to allow more than one to exist. That means that arbitrarily many parts of the program could be accessing the data at the same time. If you allow unsynchronized mutation in that situation, you can end up with data races and mangled data from those different parts making changes at the same time. That's where types such as the single-threaded `Cell` and `RefCell`, and the thread-safe `Mutex` and `RwLock` come in. They force you to go through them, and therefore synchronization, in order to mutate.
- Serow225 4y agoI kinda wish it had ended up with something like 'exc` for exclusive, or one of the options you mentioned. I think it would have made things easier for people to learn a helpful mental model.
- burntsushi 4y agoPossibly. It's one of those things that is really difficult to know. It's easy to look at what the possible benefits are because the model is more technically precise, but it's much harder to think about what the possible negatives are. The "&uniq T" model might be more technically precise, but maybe it is also more technically impenetrable and adds just one too many things that newcomers struggle with. Then again, maybe the extra precision of the model would end up helping more than hurting. It's really hard to say because of set of people for whom "&uniq T" would have helped more is non-empty. But what is the size of the set of people for whom "&mut T" actually helps more? I have no clue. But it could be large.
- Serow225 4y agoIt is interesting. When I was learning, I found “mut” way more confusing because it is less precise (it’s one level of abstraction higher, mixes “usual intent/goal” with “what does this keyword do”) so it added an extra layer that I had to mentally back out/elide every time I read the keyword.