About foreach loops

Steven Schveighoffer schveiguy at yahoo.com
Wed Jun 15 06:37:32 PDT 2011


On Tue, 14 Jun 2011 22:20:45 -0400, bearophile <bearophileHUGS at lycos.com>  
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
>

I think this is a bug.  Either i should be const during loop iteration, or  
an additional temporary should be manufactured.

It is always possible to get the above behavior using a for loop.  foreach  
should be sane.

> 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

generating an additional temporary variable should solve this.  Looks like  
the way to go.

-Steve


More information about the Digitalmars-d mailing list