Ruling out arbitrary cost copy construction?

Steven Schveighoffer schveiguy at yahoo.com
Wed Oct 27 18:41:59 PDT 2010


On Mon, 25 Oct 2010 19:06:13 -0400, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:

> On 10/7/10 8:24 CDT, Steven Schveighoffer wrote:
>> First, let me discuss why I don't like save.
>>
>> Let's classify ranges into two types. Primitive ranges are ones that
>> provide a range interface to data that otherwise does not have a range
>> interface. A good example is a container range.
>>
>> Compound ranges are ranges that combine or alter range functionality
>> from a wrapped range or set of ranges. A good example is Zip or Chain.
>>
[snip]
>>
>> We can assume that compound ranges don't contain a trivial solution, but
>> only because the range(s) they contain could implement a non-trivial
>> solution. So we can qualify those trivial, even though they don't have
>> the canonical trival solution.
[snip]
>
> I knew my retort for a while now, but neglected to write it down.
>
> David Simcha added dynamic interfaces for std.range, in which save()  
> does work and is actually instrumental. That suggests save() is useful.  
> Now, dynamic interfaces are not just an obscure corner case, so I think  
> they're here to stay and provide a compelling use case.

You mean std.range.InputRange(R) and friends?  The interfaces themselves  
are not proof they are useful.  I see zero uses in phobos of InputRange, I  
didn't look for the others.  Can you show places they are used?

The InputRangeObject and OutputRangeObject are compound ranges as I  
outlined above.  That is, they wrap another range, and as I said before,  
the fact they implement a non-trivial save is not significant.  In fact, I  
don't see them useful anywhere, you are creating an object around a  
non-object in order to satisfy an interface that nobody uses.  Again,  
these have zero uses in phobos.

This just furthers the case that save is an eager solution for an unproven  
need.

No offense to the work done, David.

Actually, there is a bug there, InputRangeObject.save is implemented like  
this:


             static if(isForwardRange!R) {
                 @property typeof(this) save() {
                     return new typeof(this)(_range);
                 }
             }

Should be:

return new typeof(this)(_range.save);

I'm willing to bet that 90% of code outside phobos does not use save, they  
just use simple assignment, knowing that it is the same as save (or not  
knowing they have to use save).

And that reminds me of another point I failed to mention:  implementing  
save does not guarantee it will be used -- assignment is not disallowed,  
and works the same as save in all currently implemented ranges.  It is  
very simple and likely to copy a range using = and not see any bugs, until  
some person eventually decides object-based ranges would be a good idea  
and uses them, and then decides to use your function.  That is, the  
compiler makes the range-implementer implement save, but does not make the  
range-user use save.  So on top of being useless, it's bug-prone.  The  
good news is that bugs are extremely unlikely to pop up since nobody (yet)  
implements the non-trivial save.

-Steve


More information about the Digitalmars-d mailing list