I have been thinking the following idea for some time and I thought I would share it here, since I have not seen discussed elsewhere.
The idea is to be able to split a struct into views such that diferent functions have limited access to the fields. And more importly we could split mutable access to a struct into mutable accesses to disjoint views of the struct.
I think the following code shows this clearly
struct Big
{
x: usize,
}
struct Composite
{
a: Big,
b: Big,
c: Big,
d: Big,
}
//We declare different views of the struct
view CompositeAB for Composite(a,b);
view CompositeAC for Composite(a,c);
view CompositeAD for Composite(a,d);
view CompositeBC for Composite(b,c);
view CompositeBD for Composite(b,d);
view CompositeCD for Composite(c,d);
//Each view could have their own implementations
impl CompositeAB
{
fn compute(&mut self)
{
self.a.x+=self.b.x;
self.b.x*=self.a.x;
self.a.x+=self.b.x;
}
}
impl CompositeAC
{
fn compute(&mut self)
{
self.a.x=(self.a+1)*(self.c.x+1);
self.c.x=(self.a+2)*(self.c.x+2);
}
}
impl CompositeAD
{
fn compute(&mut self)
{
self.a.x=(self.a+2)*(self.d.x+1);
self.d.x=(self.a+3)*(self.d.x+2);
}
}
impl CompositeBC
{
fn compute(&mut self)
{
self.b.x=(self.b+3)*(self.c.x+1);
self.c.x=(self.b+4)*(self.c.x+2);
}
}
impl CompositeBD
{
fn compute(&mut self)
{
self.b.x=(self.b+4)*(self.d.x+1);
self.d.x=(self.b+5)*(self.d.x+2);
}
}
impl CompositeCD
{
fn compute(&mut self)
{
self.c.x=(self.c+5)*(self.d.x+1);
self.d.x=(self.c+6)*(self.d.x+2);
}
}
fn main()
{
let mut thing = Composite::new();
{
//We could get mutable references to disjoint views
let ab = CompositeAB(&mut thing);
let cd = CompositeCD(&mut thing);
crossbeam::scope( move |scope| {
scope.spawn(move || {
ab.compute();
});
scope.spawn(move || {
cd.compute();
});
});
}
{
//To another combination of views
let ac = CompositeAC(&mut thing);
let bd = CompositeBD(&mut thing);
crossbeam::scope( move |scope| {
scope.spawn(move || {
ac.compute();
});
scope.spawn(move || {
bd.compute();
});
});
}
{
//The third combination
let ad = CompositeAD(&mut thing);
let bc = CompositeBC(&mut thing);
crossbeam::scope( move |scope| {
scope.spawn(move || {
ad.compute();
});
scope.spawn(move || {
bc.compute();
});
});
}
{
//This would be an error because of overlap
//let ab = CompositeAB(&mut thing);
//let ac = CompositeAC(&mut thing);
}
}
In most cases, there is only one interesting combinations of views, case in which it can be done just by including a struct as field. But when there are multiple views of interest it is not clear the implementation with the current language. I also realize that this idea could have a too narrow use case, but it could be worth discussing.