foreach on interval index by ref increment

bearophile bearophileHUGS at lycos.com
Sat Jan 21 19:38:48 PST 2012


In the last days Walter and other people are closing and fixing many bugs. But there is one bug that Walter has closed that I am not so sure about:
http://d.puremagic.com/issues/show_bug.cgi?id=5306


Regarding this code:


import core.stdc.stdio;
void main() {
    foreach (ref i; 0 .. 10) {
        printf("i = %d\n", i);
        i++;
    }
}


He says it "works as expected":

i = 0
i = 2
i = 4
i = 6
i = 8


But I don't expect and don't like that output (the same probably happens to Python programmers that see that code).

0..10 is a subset of the natural numbers, so it is an immutable entity.

And even if you see the items of a subset of the natural numbers as mutable entities, "i++" means increasing by 1 each one of them, as you see for an array:


import std.stdio;
void main() {
    auto array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    foreach (ref x; array)
        x++;
    writeln(array);
}


That prints:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


Or as you see with iota():

import std.stdio, std.range;
void main() {
    foreach (ref x; iota(0, 10)) {
        x++;
        write(x, " ");
    }
}


That prints:
1 2 3 4 5 6 7 8 9 10 


Skipping to the next number to me looks like "i++" is doing something more like a pointer increment. It's ugly, and looks bug prone. foreach is not a light syntax sugar over a for loop, it's a bit different. I have discussed a similar topic some time ago.

I think some consistency with mathematics and iota() is good to have. Also keep in mind that code like "foreach(i;N..M)" is used _everywhere_ in my programs, so being a so common D idiom it's not a secondary issue.

I suggest to turn the "i" of a foreach(i;N..M) to an immutable. So if you use "ref" it's a "immutable ref" still, so "i++" is a forbidden operation. Programmers that want to increment the loop index inside the loop itself are free to use a normal for loop, and keep the semantics of foreach loops more tidy.

Bye,
bearophile


More information about the Digitalmars-d mailing list