On Sunday, 3 February 2013 at 03:34:23 UTC, Era Scarecrow wrote:
Agreed 100%, Although a second (instance of) Dog may want to
come about and them sniff tails. That's outside access, but
it's still within the limits of the Dogs. In those cases a
context pointer could be acceptable as long as it's ensuring
the data exists (and can't return it from the function); But
overwriting one instance with a different context pointer of
another could have very curious side effects depending on
design.
struct Dog {
int id;
struct Tail {
string colorOf = "Black"; //just data.
int getId() { return id; }
}
Tail tail;
void func(ref Dog rhs) {
//tail2 retains context pointer to rhs.
Tail tail2 = rhs.tail;
writeln(tail.getId()); //5
writeln(tail2.getId()); //10
}
}
There is a bug in this code and it would not compile. Your getId
must receive an instance of Dog. A tail by itself has no dog. The
compiler cannot rewrite tail.getId() to
someImaginaryDog.tail.getId(). It's easy to think about, once you
get used to it. Your getId accesses a variable defined only in
its parent struct. The compiler detects this and requires
receiving a hidden pointer to (and *only to!*) an instance of the
parent. The resulting top-level function is:
int getId(ref Dog __d) { return __d.id; }
See? It may only access a dog, but it's *defined* in the tail.
This is the exact behavior we're looking for, and it's easy to
implement and causes no real trouble, as far as I can see.
Dog dog1 = Dog(5);
Dog dog2 = Dog(10); dog2.tail.colorOf = "White";
dog1.func(dog2);
//context pointer of d2 thrown away after copy,
//unless opAssign declared and does something.
dog1.tail = dog2.tail;
assert(d1.id == 5); //untouched
assert(d1.tail.colorOf == "White");
At which case the tail if it's allowed to be copied should be
related but not strictly required to be updated or relied on
Dog for behavior.
Guess it takes a few rules and experiments to find the right
balance of accessibility vs reliability vs flexibility.
With the bug removed, will any of these issues pop up? My guess
is no.