Move semantics for D

Jonathan M Davis jmdavisProg at gmx.com
Fri Jul 13 15:26:45 PDT 2012


On Friday, July 13, 2012 14:11:44 monarch_dodra wrote:
> But I still feel that the internal call to opSlice/copy is really
> a just trap disguised as a safety net...

Yeah. Kind of.

The thing is that there's no way around the fact that structs and arrays are 
effectively value types as far as ranges go, whereas classes are reference 
types. If you want them to be copied consistently, you need to use save. If 
you don't care whether a copy is made or not, then you don't worry about it.

But foreach has to be treated specially with ranges anyway, because of 
strings.

foreach(e; str) {}

is going to iterate over char, not dchar, whereas strings are ranges of dchar. 
So, if you iterate over a range generically, you need to do

foreach(ElementType!R e; range) {}

So, you have to be careful with foreach already, and having it _not_ save but 
having it copy the range automatically (and therefore implicitly saving for 
non-reference type forward ranges) is completely consistent with how it works 
with passing ranges to functions, so in that sense, it really isn't all that 
bad. If anything, things are _more_ consistent that way.

The only way to really solve the save problem would be to disallow forward 
ranges which were reference types (which you could mostly do by disallowing 
classes, but I don' think that there's any real way to statically check 
whether a struct is a reference type or not). Then save wouldn't be needed, 
and ranges would all function the same as long as no one made structs which 
were reference types into ranges. But that would also cut off some useful 
idioms (sometimes, you _want_ a range to be consumed by a function rather than 
being implicitly copied - which is why I added std.range.RefRange for 2.060). 
So, I don't know of any way to really fix the problem. You need save to make it 
possible to copy reference types, and there's no way to reasonably avoid 
having to deal with both value type and reference type ranges.

So, we just deal with it. Unfortunately, far too often, the result of that is 
that value type ranges work properly and reference type ranges don't, since 
range-based functions are usually tested with just value types ranges, but 
improved testing fixes that, and that's not all that hard to do.

- Jonathan M Davis


More information about the Digitalmars-d mailing list