Hacker News new | past | comments | ask | show | jobs | submit login
Interior Mutability Patterns in Rust (pitdicker.github.io)
84 points by fanf2 on Jan 4, 2020 | hide | past | favorite | 12 comments



Interior mutability to always seemed like a hack around the borrow check and type system instead of just fixing those parts of the language itself. If the single mutable borrow idea isn't working out so much that you need to have idioms like interior mutability, maybe you should relax the requirements or provide a more direct of doing this.

Why not introduce a new borrow notation besides const and mut, add a multimut or something that makes it very clear instead of these hacky solutions.


It's not a hack, although I can't really fault you for thinking otherwise. The borrow notations are & (shared) and &mut (exclusive, guarantees mutability regardless of type). 'Interior mutability' is a way of enabling shared data to be mutable. See https://limpet.net/mbrubeck/2019/02/07/rust-a-unique-perspec... for a more principled explanation, which even improves on Rust's official docs - this is probably best read in combination w/ OP's series.


I know what it is. I've been involved with Rust on and off for about 4 years (now more off than on, but periodically stepping back in).

IM has always seemed like a really bad wart - an intentional breaking of the borrow checking through idiom rather than a language construct. Just as `&` is an shared const ref, `&mut` is an exclusive mutable ref, but for some reason when you get to shared mutable instead of making `multimut&` or something, the language invokes cells then has the audacity to straight-face proclaim you can share mutable references.

I guess if they made `multimut&` ref they would have to admit is is possible I guess. The difference between the syntactic and cell-based representation of that type of share mutable reference always seemed like no real difference.

I do a lot of C++ and having to basically do hygienic macros though template metaprogramming is on the same level. I'd rather just have hygienic macros. Cells are the Rust equivalent of removing const through template without ever having to cast it away explicitly. An intentional breaking of const through idiom rather than syntax.

If tomorrow a shorthand cell was introduced like `shm&` (similar to how `?` was introduced as shorthand for dealing with Result types), it would bring it into the realm of syntax and be much clearer what was going on.

Cell seems like a straight up step around the borrow checker for shared mutability. It should look like the other references.


That's the thing, & really has nothing to do with constness or immutability, and a consistent description of the language should make that clear. It's not a language problem, it's a documentation problem.

And the language has quite simply moved in the opposite direction to that of having more shorthand syntax. Box<> and the then-equivalent of Rc<> used to have their own shorthand sigils in Rust, but these were replaced with writing out the type constructors. Again, if it's reasonably consistent, there's nothing wrong with that. It's quite different from the '?' syntax which is replacing what used to be a special macro, 'try!'. Macros can do almost anything with the code and are pretty hackish, type constructors not really.


> That's the thing, & really has nothing to do with constness or immutability

No, that means 'reference', but the `mut` and lack of work mean exclusive mutability and const respectively. So another term that means share mutability makes sense.

> And the language has quite simply moved in the opposite direction to that of having more shorthand syntax

Most definitely not. Recent examples are `?` and `async` that replace types with syntax. And coming up the pipe is going to be most coroutines are probably going to get their own syntax too. While year ago that might have been the case (and I think Box should have retained its sigil), the more recent trend is back in the other direction.

Also, not that we already have `mut` and `` (no marker), mixing forms would be bad at this time, we instead of `shm` or something we get cells that correspond to the `mut` for shared mutability.

And regardless of the syntax question, it is still a massive end around the borrow checker and people refuse to admit how hacky it is.


> No, that means 'reference', but the `mut` and lack of work mean exclusive mutability and const respectively.

You keep saying this, but it's just not the most straightforward way of understanding the language - no matter what the official docs say at this time. It might be fair to complain about the lack of true 'const', 'pure' etc. specifiers in Rust, but to say that & references are 'const' references is just not sensible IMHO. It might make more sense to make a similar claim about C++, where the 'mutable' keyword really does seem to be a hack like you describe. But C++ has no borrow checker in the first place hence no such motive for 'interior' mutability - so it's in a totally different situation.


Your complaint is purely syntactic- `&Cell<T>` exactly the same thing as `&multimut T` semantically.

Other forms of interior mutability genuinely are more than a tweak to borrowck- `RefCell` has a counter, `Mutex` adds synchronization, etc.


Interior mutability is a principled way to relax the requirements. Multimut exists for really low-level code; it's spelled *mut.


Saying it doesn't make it true. There is nothing principled about it - a pure hack around the borrow checker. It seems to be one of the most unprincipled ways - more like casting away const in c++

And I know what unsafe pointers are, but the special keyword would allow the compiler to understand more about the code's intentions.

edit: I take that back. It seems worse. It would as if there was a way to get rid of const by a series of assignments without ever having to explicitly cast it away.


Don't miss the author's second installment to this series. Navigate to the index of the blog to see part 2 at the top.


GhostCell seems worth reading more into.

OnceCell is being discussed as part of https://github.com/rust-lang/rfcs/pull/2788 too.


Really enjoyed the read! Two minor things I found: downgrade(&self) should be downgrade(self), and rw2 and rw3 have TCell parameters, should these not be QCells?




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: