Thread overview
Reference or Value Semantics for Graph Traversal Range
Feb 18, 2015
Nordlöw
Feb 18, 2015
Tobias Pankrath
Feb 18, 2015
Nordlöw
Feb 18, 2015
Nordlöw
Feb 18, 2015
Nordlöw
Feb 18, 2015
Tobias Pankrath
Feb 18, 2015
Nordlöw
Feb 18, 2015
Tobias Pankrath
February 18, 2015
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?
February 18, 2015
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.
February 18, 2015
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.

February 18, 2015
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


February 18, 2015
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!
February 18, 2015
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);
}







February 18, 2015
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?
February 18, 2015
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.
February 18, 2015
On Wednesday, 18 February 2015 at 14:55:58 UTC, Tobias Pankrath wrote:
> It's the same with arrays.

Ahh, you're right. Thanks.