I'm thinking about ranges I can think of similar design of the input range, but with different pros and cons. Obviously not for/in D. Currently ranges has 3 primitive operations, and they can be translated from foreach like:

for (auto __r = range; !__r.empty; __r.popFront())
{
    auto e = __r.front;
    ...
}

I'm thinking of design where range would have only 2 primitive operations:

bool popFront() // returns true if current will have an element front // it may be called only if popFrount (would) have returned true

foreach would be translated to:

while (auto r = r.popFront())
{
    auto e = __r.front;
    ...
}

This design results in following differences

1) 2 primitive operations (empty and popFront) are merge into one less primitive

2) it will result in less calls per item (2 instead for 3)

3) it is not possible to "ask" a range if it's empty more times per iteration of one item

4) it does _not_ requires range to be in "ready" state immediately after construction. That means that popFront needs to be called firstly, before front can be. This I feel is biggest change. Since D ranges are required to have front ready immediately after their construction. Which for some non trivial ranges can seem as less effective/convenient/expected.

I would be interested what do you think about this possible design. Does it have some special flaws in general, or specifically for D. What are the advantages of current design. Do you think it would be reasonable in some other language? What do you think is better in practice from point of view of implementors and users of range: that range has ready front immediately, or better to have it ready only after first popFront call.

Thank you.

Reply via email to