About foreach loops
KennyTM~
kennytm at gmail.com
Wed Jun 15 03:04:07 PDT 2011
On Jun 15, 11 10:20, bearophile wrote:
> This post is about some characteristics of the D foreach that has nagged me for some time.
>
> This is a little Python 2.6 program:
>
>
> for i in xrange(10):
> i += 1
> print i,
>
>
> Its output shows that you are allowed to modify the iteration variable (contents of the iteration name), but the iteration goes on with no change:
> 1 2 3 4 5 6 7 8 9 10
>
>
> Similar code in D using foreach shows a different story:
>
> import std.stdio;
> void main() {
> foreach (i; 0 .. 10) {
> i += 1;
> write(i, " ");
> }
> }
>
> The output:
> 1 3 5 7 9
>
>
> In my opinion this is a bit bug-prone because in real code there is some risk of modifying the iteration variable "i" by mistake. (Note: here I am not talking about D for() loops. They are OK, their semantics is transparent enough. foreach() loops are less transparent and they *look* higher level than for() loops). I'd like the iteration variable to act as being a copy of the true loop variable as in Python. If this is a bit bad for foreach performance, then I'd like the compiler to forbid the mutation of the foreach iteration variable inside the foreach body. Is this even possible?
>
>
> Currently you can't solve the problem adding a const(int) to the iteration variable:
>
> import std.stdio;
> void main() {
> foreach (const(int) i; 0 .. 10) { // line 3
> write(i, " ");
> }
> }
>
>
> DMD gives:
> test.d(3): Error: variable test.main.i cannot modify const
>
>
> This is a related but different thing:
> http://d.puremagic.com/issues/show_bug.cgi?id=5255
>
> Bye,
> bearophile
Perhaps the `foreach` loop
foreach (i; a .. b)
loop_body;
should be rewritten into
for (auto __foreachtemp1234 = a;
__foreachtemp1234 < b;
++ __foreachtemp1234)
{
const i = __foreachtmp1234;
loop_body;
}
this would prevent the loop index be modified inside the loop body.
Similarly, the indiced array loop
foreach (i, elem; arr)
loop_body;
should be rewritten into
for (size_t __foreachtemp5678 = 0, __foreachtemp5679 = a.length;
__foreachtemp5678 < __foreachtemp5679;
++ __foreachtemp5678)
{
const i = __foreachtemp5678;
auto elem = arr[__foreachtemp5678];
loop_body;
}
bearophile, have you filed an enhancement request for this?
More information about the Digitalmars-d
mailing list