Proposal to deprecate "retro.source"

monarch_dodra monarchdodra at gmail.com
Thu Nov 8 01:56:38 PST 2012


On Thursday, 8 November 2012 at 09:18:54 UTC, Jonathan M Davis 
wrote:
> In the case of retro, I think that it would good to have source 
> exposed for
> std.container's use. It's easy for std.container to understand 
> what retro's
> supposed to do, and use it accordingly, and I think that it 
> would be silly for
> it have to call retro on the retroed range to do that. I do 
> agree however that
> in general, it doesn't make sense to access source.

Yes, accessing the original range is useful, but AFAIK, container 
doesn't use retro in any way. It does it with take (which also 
has a source field). For take, there is no way to extract the 
source other than with a specialized function.

regarding retro, I find it silly it has a "source" field at all, 
when the original could just be retrieved using retro again (and 
just as efficiently). I don't see any way using source over retro 
could be useful to anyone at all, except for actually 
implementing retro().retro() itself (in which case a _source 
would have done just as well).

> As for
>
>> The problem though is in the way the documentation "The 
>> original range can be accessed by using the source property" 
>> and "Applying retro twice to the same range yields the 
>> original range": Looks like we forgot to notice these two 
>> sentences are contradicting.
>
> I don't see anything contradictory at all. If you call retro on 
> a retroed
> range, you get the original. If you access source, you get the 
> original.
> Where's the contradiction?

In "If you access source, you get the original". This is only 
true if the "The original" is not itslef already a retro. This 
mind sound silly, but you may not have control of this. For 
example,

For example, imagine you want a find function that searches from 
the end, and returns the result of everything before the match:

//----
import std.stdio;
import std.algorithm;
import std.range;

auto findBefore(R)(R r, int n)
{
     auto a = r.retro();
     auto result = a.find(n);
     static assert(is(typeof(result) == typeof(r.retro()))); 
//result is a retro
     return result.source; //Error: undefined identifier 'source'
}

void main()
{
     auto a = [0, 1, 2, 3, 4, 5];
     a.findBefore(3).writeln(); //expect [1, 2, 3]
     a.retro().findBefore(3).writeln(); //expect [5, 4, 3]

     auto b = indexed([2, 1, 3, 0, 4, 5], [3, 1, 0, 2, 4, 5]);
     assert(b.equal(a)); // b is [0, 1, 2, 3, 4, 5]
     b.retro().findBefore(3).writeln(); // produces [2, 1, 3, 0, 
4, 5]...
}
//----
In "findBefore3", one should expect getting back the "original 
range", but that is not the case. However, using "return 
result.retro()"; works quite well.

Things get even stranger if the underlying range also as a 
"source" filed itself (because of the auto return type).

Both the issues can be fixed with "return result.source;"

--------
I don't think there is anything to be gained using "source". I 
don't think it would be worth deprecating it either, and it is 
not a huge issue, but I think the documentation should favor the 
use of double retro over source, or even mention source at all.

Less surprises is always better.


More information about the Digitalmars-d mailing list