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.