Struct that destroys its original handle on copy-by-value
Joseph Rushton Wakeling via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Aug 1 05:03:19 PDT 2015
On 31/07/15 19:21, Ali Çehreli via Digitalmars-d-learn wrote:
> On 07/26/2015 04:29 AM, Joseph Rushton Wakeling via Digitalmars-d-learn wrote:
>
> > is this design idea even feasible in principle, or just a bad
> > idea from the get-go?
>
> As I understand it, it is against one of fundamental D principles: structs are
> value types where any copy can be used in place of any other.
>
> I expect there are examples where even Phobos violates it but the struct
> documentation still says so: "A struct is defined to not have an identity; that
> is, the implementation is free to make bit copies of the struct as convenient."
>
> http://dlang.org/struct.html
That really feels very bad for the problem domain I have in mind -- random
number generation. No implementation should be free to make copies of a random
number generator "as convenient", that should be 100% in the hands of the
programmer!
> > And if feasible -- how would I go about it?
>
> Disallowing automatic copying and providing a function comes to mind.
Yes, I considered that, but I don't think it really delivers what's needed :-(
Let me give a concrete example of why I was thinking in this direction.
Consider RandomSample in std.random. This is a struct (a value type,
instantiated on the stack). However, it also wraps a random number generator.
It needs to be consumed once and once only, because otherwise there will be
unintended statistical correlations in the program. Copy-by-value leads to a
situation where you can accidentally consume the same sequence twice (or
possibly, only _part_ of the sequence).
Now, indeed, one way is to just @disable this(this) which prevents
copy-by-value. But then you can't do something natural and desirable like:
iota(100).randomSample(10, gen).take(5).writeln;
... because you would no longer be able to pass the RandomSample instance into
`take`.
On the other hand, what you want to disallow is this:
auto sample = iota(100).randomSample(10, gen);
sample.take(5).writeln;
sample.take(5).writeln; // statistical correlations result,
// probably unwanted
The first situation is still possible, and the second disallowed (or at least,
guarded against), _if_ a copy-by-value is finalized by tweaking the source to
render it an empty range.
I would happily hear alternative solutions to the problem, but that's why I was
interested in a struct with the properties I outlined in my original post.
More information about the Digitalmars-d-learn
mailing list