front stability

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Thu Jun 2 05:51:18 PDT 2016


I have always treated ranges with this expectation:

1. front gets you the current element of the range. Calling front 
multiple times without calling popFront should get you the same value.
2. popFront moves you to the next element of the range if it exists.

However, there are some ranges which can violate this. For example map:

int i = 0;
auto r = iota(int.max).map!((a) => ++i);

auto e1 = r.front;
auto e2 = r.front;
assert(e1 + 1 == e2);

But I consider this a programming error. It's acceptable to me that it's 
possible to write bugs using ranges, no programming language is immune 
to that.

However, Joseph Wakeling pointed out[1] the generate range[2]:

auto r = generate(() => ++i);

// same result

But unlike map, there isn't a way to make generate work as a proper 
range, because as Joe pointed out, popFront does nothing, front does all 
the work that popFront would do.

There was a bit of discussion when this function was being vetted[3], 
and IMO, this did not result in the correct function.

For example, generate.popFrontN does nothing. generate.drop does 
nothing. And of course, calling front multiple times does not yield the 
same answer, unless you provide a lambda that does the same thing every 
time (a useless case).

The counter-argument seems to be that if you cache the front element, 
then then making a copy of the range via take can repeat the cached 
element[4]. I find this argument severely lacking -- non-forward ranges 
are not meant to be copied and expected to operate properly, it's why we 
require calling save.

I'd say violating the expectations of what popFront and front do is more 
egregious than a particular use case, no matter how valid that case is. 
I'd like to fix this bug, but I see there were quite a few major D 
contributors in the camp that wanted this function to behave the way it 
is. So I'd rather first debate the merits here.

-Steve

[1] https://forum.dlang.org/post/ttyzjfmegkmbluumiczf@forum.dlang.org
[2] http://dlang.org/phobos/std_range.html#.generate
[3] https://github.com/dlang/phobos/pull/2606
[4] https://github.com/dlang/phobos/pull/2606#issuecomment-58740715


More information about the Digitalmars-d mailing list