I don't think this is a good idea. Say you have a class with range methods and add opApply later. Only the opApply delegate receives a type other than size_t for the first argument. Now the foreach line infers a differnt type for i and code in the outside world will break.

More importantly, this gets in the way of behaviour which may be desirable later, foreach being able to unpack tuples from ranges. I would like if it was possible to return Tuple!(A, B) from front() and write foreach(a, b; range) to interate through those thing, unpacking the values with an alias, so this...

foreach(a, b; range) {
}

... could rewrite to roughly this. (There may be a better way.)

foreach(_someInternalName; range) {
    alias a = _someInternalName[0];
    alias b = _someInternalName[1];
}

Then to get a counter with a range, we could follow Python's example and use an enumerate function, which would take an existing range and wrap it with a counter, so T maps to Tuple!(size_t, T).

foreach(index, value; enumerate(range)) {
}

Which is rewritten to roughly this.

foreach(_bla; enumerate(range)) {
    alias index = _bla[0];
    alias value = _bla[1];
}

If we follow Python's example again, we could also support this nested unpacking.

// Now written with UFCS instead.
foreach(index, (index_again, value); range.enumerate.enumerate) {
}

Which can rewrite to roughly this.

foreach(_bla; range.enumerate.enumerate) {
    alias index = _bla[0];
    alias index_again = _bla[1][0];
    alias value = _bla[1][1];
}

I got off on kind of a tangent there, but there you go.

Reply via email to