Indices for or references to mutable objects? Or something else?

Dear Rustaceans,

I am working on a statistical model M. M contains different sub-models: patterns P_i and distributions D_j. I am using patterns and distributions by combining them. For this post, let us assume that I use pairs of the form (P, D). In reality, the situation is slightly more complex, but this is the essence it boils down to.

I have to mutate my model many times. The mutations I do boil down to changing, adding, or removing patterns and distributions. Each mutation only affects a small portion of the model.

Because I have to mutate M so many times, I have implemented repositories for both patterns and for distributions. The repositories track the learned elements, and the elements are referenced via index structs of the form PatternReference(usize) or DistributionReference(usize). Let us call them ref P and ref D for short.

This means that my pairs are of the form (ref P, ref D). They are completely opaque and I e.g. cannot Display them in a meaningful way. I also have no safety regarding whether referenced elements actually exist. I do not like this. However, I don't know how to do this better. I would like to use references, but then I think I cannot mutate my model that easily any more – since every mutation only affects a small fraction of the patterns and distributions, having to drop and thus later re-instate all references seems like a terrible overhead to me.

Do any of you have any advice?

Thanks in advance!

TL;DR: I am not sure how to handle references to items that I feel should be mutable and thus I get a lot of dependencies between parts of my model that I feel shouldn't be that dependent on each other.

Using indices as refs is a common approach used to implement ref heavy datastructures, like graphs. In that sense, you’re not alone :slight_smile:.

One thing you can do is put your patterns and distributions in a Rc<RefCell<...>> and use interior mutability (via RefCell’s borrow_mut). PatternReference and DistributionReference would then have a Weak<RefCell<...>> reference to the underlying value. Weak would ensure that if all other strong refs are dropped (such as in your repository), the Weak doesn’t keep the value alive - you won’t be able to get a Rc out of it and thus you’ll know that the value has been dropped elsewhere.

Hey! Thanks for your reply :slight_smile:

I will read up on Rc -- having weak pointers might make some things much more comfortable.