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