On 10/21/2015 04:36 PM, Andrei Alexandrescu wrote:
On 10/21/2015 10:21 AM, Timon Gehr wrote:


I still think those should be mutable by default in order to have
painless interchangeability with other value type containers. Why should
corresponding ephemeral and persistent containers have different
interfaces?

I assume you envision code using those to look as follows?

FunSet!int a;
a=a.with_(1);
auto b=a;
a=a.with_(2);
a=a.with_(3);
// b = {1}, a={1,2,3};

I think this should be allowed too:

FunSet!int a;
a.insert(1);
auto b=a;
a.insert(2);
a.insert(3);
// b = {1}, a={1,2,3};

One of the two versions should be automatically implemented via UFCS.

I recall you and I discussed this briefly in the past, but forgot the
conclusion.
...

IIRC the conclusion was postponed. :-)

So are you saying that a.insert(1) is really rebinding a to be its
former value plus a new slot? I.e a.insert(1) is the same as a =
a.with_(1)? That would work, but only if former reads of a refer to the
old data. E.g.:

FunSet!int a;
auto b = a;
assert(a.empty && b.empty);
a.insert(1);
assert(!a.empty && b.empty);

Right?


Andrei

Exactly. There would be no mutable aliasing. This way, the persistent data type can behave like a mutable value type, such as a COW or eager copy variant, but with nicer/different performance characteristics. It would be great if exchanging different implementation strategies for value semantics will be as seamless as possible. (If the initially chosen strategy turns out to be wrong, this makes the fix easy.) Of course, the implementation of the persistent data structure will be in terms of non-mutating and possibly O(1)-COW operations only.


Reply via email to