www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Reference or Value Semantics for Graph Traversal Range

reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
I've written a Dijkstra-style graph traversal range at

https://github.com/nordlow/justd/blob/master/knet/traversal.d#L105

that needs to internally store the AA distance map in member 
variable distMap.

1.

All the data members except distMap have reference semantics. 
Therefore I've made my range a class instead of a struct. Is this 
the correct way to do it?

2.

To make it a ForwardRange I've also add a save() member. For now 
I've hardcoded the single member that needs to be duped. Is this 
correct way of doing it?
Feb 18 2015
parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
On Wednesday, 18 February 2015 at 13:37:57 UTC, Nordlöw wrote:
 I've written a Dijkstra-style graph traversal range at

 https://github.com/nordlow/justd/blob/master/knet/traversal.d#L105

 that needs to internally store the AA distance map in member 
 variable distMap.

 1.

 All the data members except distMap have reference semantics.
I thought AAs had reference semantics.
 Therefore I've made my range a class instead of a struct. Is 
 this the correct way to do it?
Neither false nor necessary. You could use a struct just as well.
 2.

 To make it a ForwardRange I've also add a save() member. For 
 now I've hardcoded the single member that needs to be duped. Is 
 this correct way of doing it?
That's how I'd do it.
Feb 18 2015
parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 18 February 2015 at 13:53:17 UTC, Tobias Pankrath 
wrote:
 All the data members except distMap have reference semantics.
I thought AAs had reference semantics.
Me too, but the indeed have value semantics. See for example: unittest { string[int] x; auto y = x; x[0] = "zero"; assert(x != y); } This makes usage of storing internal state in Ranges bug-prone. Isn't there some way to store an AA in reference wrapper? This would simplify my .save member.
Feb 18 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 2/18/15 8:59 AM, "Nordlöw" wrote:
 On Wednesday, 18 February 2015 at 13:53:17 UTC, Tobias Pankrath wrote:
 All the data members except distMap have reference semantics.
I thought AAs had reference semantics.
Me too, but the indeed have value semantics. See for example: unittest { string[int] x; auto y = x; x[0] = "zero"; assert(x != y); }
This is a well known problem. An UNINITIALIZED AA has not yet been allocated, and so it's reference is null. But once initialized, it DOES have reference semantics: string[int] x; x[0] = "zero"; auto y = x; x[1] = "one"; assert(x == y); And to anticipate your question, no there is no way (yet) to create an empty but initialized AA. -Steve
Feb 18 2015
next sibling parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 18 February 2015 at 14:07:01 UTC, Steven 
Schveighoffer wrote:
 But once initialized, it DOES have reference semantics:

 string[int] x;
 x[0] = "zero";
 auto y = x;
 x[1] = "one";
 assert(x == y);
Ok, great! I always initialize distMap with firstNd in the DijkstraWalk.this so that avoids the problem then. Thanks alot!
Feb 18 2015
prev sibling parent reply =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 18 February 2015 at 14:07:01 UTC, Steven 
Schveighoffer wrote:
 An UNINITIALIZED AA has not yet been allocated, and so it's 
 reference is null.
What's reason for uninitialized AA not behaving in the same way as arrays do?
Feb 18 2015
parent reply "Tobias Pankrath" <tobias pankrath.net> writes:
On Wednesday, 18 February 2015 at 14:38:24 UTC, Nordlöw wrote:
 On Wednesday, 18 February 2015 at 14:07:01 UTC, Steven 
 Schveighoffer wrote:
 An UNINITIALIZED AA has not yet been allocated, and so it's 
 reference is null.
What's reason for uninitialized AA not behaving in the same way as arrays do?
It's the same with arrays.
Feb 18 2015
parent =?UTF-8?B?Ik5vcmRsw7Z3Ig==?= <per.nordlow gmail.com> writes:
On Wednesday, 18 February 2015 at 14:55:58 UTC, Tobias Pankrath 
wrote:
 It's the same with arrays.
Ahh, you're right. Thanks.
Feb 18 2015
prev sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
On Wednesday, 18 February 2015 at 13:59:43 UTC, Nordlöw wrote:
 On Wednesday, 18 February 2015 at 13:53:17 UTC, Tobias Pankrath 
 wrote:
 All the data members except distMap have reference semantics.
I thought AAs had reference semantics.
Me too, but the indeed have value semantics. See for example: unittest { string[int] x; auto y = x; x[0] = "zero"; assert(x != y); } This makes usage of storing internal state in Ranges bug-prone. Isn't there some way to store an AA in reference wrapper? This would simplify my .save member.
Because y does not alias x, it's a null pointer like AA. This class is clearly a reference type, but the assert holds as well. class C { int i; } void main() { C c1; C c2 = c1; c1 = new C(12); assert(c1.i != c2.i); }
Feb 18 2015