Earlier quoted context omitted.
Agreed! While it's not considered "idiomatic" Rust (from all my conversations on the Rust discords), I think that interior mutability is a totally fine thing to reach for in certain cases, at the upper levels of one's architecture. But then, once your code has RefCell everywhere, you're incurring runtime overhead, at which point one might as well switch to a language that makes those tradeoffs easier to wield. This'l…
> But then, once your code has RefCell everywhere, you're incurring runtime overhead The runtime overhead is quite trivial (a single word per object IIRC, which is accessed w/ simple increments/decrements/checks as needed) and work is ongoing on abstractions that don't incur any hidden overhead (called 'GhostCell').
If it's a rather short-lived object and we don't need to reuse its location, it can be in a Vec, which involves bounds checking and O(logN) calls to malloc, which is not amortized. Sometimes we can put short-lived objects in an arena, which is the best option, but they are very memory hungry, which has its own costs.
If it's longer lived, we can use a Vec with indices or a type-pool, but we risk use-after-"release", which can be a privacy risk and defeats some of the nice "sanity" properties of Rust code (this is still a good option in some cases, IMO).
If it's longer lived, and we don't want those drawbacks, we have to fall back on something like Rc or generational indices, which both have their runtime costs.
IME, only a very specific kind of use case can avoid any of this runtime overhead. When you get to the more complex use cases, especially with lots of unavoidable state, these overheads appear more and more, and make the whole situation a little less clear-cut.
(This was a rather hand-wavy explanation, I can make it more accurate if you'd like)