Move semantics for D

monarch_dodra monarch_dodra at gmail.com
Sat Jul 14 01:21:58 PDT 2012


On Friday, 13 July 2012 at 22:27:01 UTC, Jonathan M Davis wrote:
> 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

Very good points. I appreciate your answer.

I guess I should consider the "copy" the standard byproduct of 
"passing to foreach" => I should _also_ remember to save before 
passing a range to a function.


More information about the Digitalmars-d mailing list