Jump to page: 1 2
Thread overview
suggested change to foreach index
Jun 07, 2006
BCS
Jun 08, 2006
Ameer Armaly
Jun 08, 2006
Regan Heath
Jun 08, 2006
Ameer Armaly
Jun 08, 2006
BCS
Jun 08, 2006
Derek Parnell
Jun 08, 2006
BCS
Jun 08, 2006
Sean Kelly
Jun 08, 2006
Deewiant
Jun 08, 2006
Sean Kelly
Jun 08, 2006
Deewiant
Jun 08, 2006
BCS
Jun 08, 2006
Tom S
Jun 08, 2006
Derek Parnell
Jun 08, 2006
Sean Kelly
Jun 10, 2006
Bruno Medeiros
Jun 10, 2006
Deewiant
Jun 10, 2006
BCS
June 07, 2006
I often find my self doing something like this:

<code>
int i
char[] arr;

foreach(int j, c; arr)
	if(' ' == c)
	{
		i=j;	// copy j out of foreach's scope
		break;
	}

if(i < arr.length)
{
	arr = arr.dup;
		// use copy of j
	foreach(inout c; arr[i..$])
		if(' ' == c) c = '_';
}
</code>

In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i.

<code>
int i
char[] arr;

foreach(int i, c; arr)
	if(' ' == c)
		break;

// i keeps the value from the last time through
...
</code>


Thoughts comments??
June 08, 2006
"BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com...
>I often find my self doing something like this:
>
> <code>
> int i
> char[] arr;
>
> foreach(int j, c; arr)
> if(' ' == c)
> {
> i=j; // copy j out of foreach's scope
> break;
> }
>
> if(i < arr.length)
> {
> arr = arr.dup;
> // use copy of j
> foreach(inout c; arr[i..$])
> if(' ' == c) c = '_';
> }
> </code>
>
> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i.
>
> <code>
> int i
> char[] arr;
>
> foreach(int i, c; arr)
> if(' ' == c)
> break;
>
> // i keeps the value from the last time through
> ...
> </code>
>
>
> Thoughts comments??
Wouldn't a function return serve a similar if not identical purpose?


June 08, 2006
On Wed, 7 Jun 2006 20:27:51 -0400, Ameer Armaly <ameer_armaly@hotmail.com> wrote:
> "BCS" <BCS@pathlink.com> wrote in message
> news:e67p90$rol$1@digitaldaemon.com...
>> I often find my self doing something like this:
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int j, c; arr)
>> if(' ' == c)
>> {
>> i=j; // copy j out of foreach's scope
>> break;
>> }
>>
>> if(i < arr.length)
>> {
>> arr = arr.dup;
>> // use copy of j
>> foreach(inout c; arr[i..$])
>> if(' ' == c) c = '_';
>> }
>> </code>
>>
>> In this case it would be nice to be able to use a variable in the outer
>> scope as the index in the foreach, e.i.
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int i, c; arr)
>> if(' ' == c)
>> break;
>>
>> // i keeps the value from the last time through
>> ...
>> </code>
>>
>>
>> Thoughts comments??
> Wouldn't a function return serve a similar if not identical purpose?

Requiring you to put the foreach in a function? Probably.

At the very least we need some way to indicate we want the behaviour as it really shouldn't use variables external to the foreach by default. eg.

int i;
char[] arr;

foreach(inout int i, c; arr) {}

or

foreach(inout i, c; arr) {}

or something. Something/anything to indicate the 'i' in the loop is the 'i' from outside the loop. Or, perhaps another block which is executed with the foreach variables when the loop doesn't terminate normally:

foreach(int i, c; arr) {
}
else {
  //comes here if you use 'break' in foreach
  //i, and c have the last values they had in the loop.
  //what happens in the 'inout c' cases?
}

Regan
June 08, 2006
"Regan Heath" <regan@netwin.co.nz> wrote in message news:optasxzhwe23k2f5@nrage.netwin.co.nz...
> On Wed, 7 Jun 2006 20:27:51 -0400, Ameer Armaly <ameer_armaly@hotmail.com> wrote:
>> "BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com...
>>> I often find my self doing something like this:
>>>
>>> <code>
>>> int i
>>> char[] arr;
>>>
>>> foreach(int j, c; arr)
>>> if(' ' == c)
>>> {
>>> i=j; // copy j out of foreach's scope
>>> break;
>>> }
>>>
>>> if(i < arr.length)
>>> {
>>> arr = arr.dup;
>>> // use copy of j
>>> foreach(inout c; arr[i..$])
>>> if(' ' == c) c = '_';
>>> }
>>> </code>
>>>
>>> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i.
>>>
>>> <code>
>>> int i
>>> char[] arr;
>>>
>>> foreach(int i, c; arr)
>>> if(' ' == c)
>>> break;
>>>
>>> // i keeps the value from the last time through
>>> ...
>>> </code>
>>>
>>>
>>> Thoughts comments??
>> Wouldn't a function return serve a similar if not identical purpose?
>
> Requiring you to put the foreach in a function? Probably.
>
It just seems to me that if you want something to loop over a set and inform you of the stopping point, that's the natural place for a function, though I could be overlooking some corner cases.
> At the very least we need some way to indicate we want the behaviour as it really shouldn't use variables external to the foreach by default. eg.
>
> int i;
> char[] arr;
>
> foreach(inout int i, c; arr) {}
>
> or
>
> foreach(inout i, c; arr) {}
>
> or something. Something/anything to indicate the 'i' in the loop is the 'i' from outside the loop. Or, perhaps another block which is executed with the foreach variables when the loop doesn't terminate normally:
>
> foreach(int i, c; arr) {
> }
> else {
>   //comes here if you use 'break' in foreach
>   //i, and c have the last values they had in the loop.
>   //what happens in the 'inout c' cases?
> }
>
> Regan


June 08, 2006
On Wed, 07 Jun 2006 17:04:09 -0700, BCS wrote:

> I often find my self doing something like this:
> 
> <code>
> int i
> char[] arr;
> 
> foreach(int j, c; arr)
> 	if(' ' == c)
> 	{
> 		i=j;	// copy j out of foreach's scope
> 		break;
> 	}
> 
> if(i < arr.length)
> {
> 	arr = arr.dup;
> 		// use copy of j
> 	foreach(inout c; arr[i..$])
> 		if(' ' == c) c = '_';
> }
> </code>
> 
> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i.
> 
> <code>
> int i
> char[] arr;
> 
> foreach(int i, c; arr)
> 	if(' ' == c)
> 		break;
> 
> // i keeps the value from the last time through
> ...
> </code>
> 
> Thoughts comments??

I see what you mean but have you tried this ...

    int i;
    char[] arr;
    foreach(int j, c; arr)
        if(' ' == c)
        {
            arr = arr.dup;
            foreach(inout c; arr[j..$])
               if(' ' == c) c = '_';
            break;
        }

-- 
Derek
(skype: derek.j.parnell)
Melbourne, Australia
"Down with mediocracy!"
8/06/2006 11:12:32 AM
June 08, 2006
In article <cs4o03emrdkm$.b5qasiolumf7.dlg@40tude.net>, Derek Parnell says...
>On Wed, 07 Jun 2006 17:04:09 -0700, BCS wrote:
>> I often find my self doing something like this:
[...]
>> 
>> <code>
>> int i
>> char[] arr;
>> 
>> foreach(int i, c; arr)
>> 	if(' ' == c)
>> 		break;
>> 
>> // i keeps the value from the last time through
>> ...
>> </code>
>> 
>> Thoughts comments??
>
>I see what you mean but have you tried this ...
>
>    int i;
>    char[] arr;
>    foreach(int j, c; arr)
>        if(' ' == c)
>        {
>            arr = arr.dup;
>            foreach(inout c; arr[j..$])
>               if(' ' == c) c = '_';
>            break;
>        }
>

That would work but its not vary expandable. Try doing that for five or six loops. The proposed solution is just a lot cleaner, even in the two loop case.

Or how about doing that with something like:

char[] arr;
int j=0, i, skip;

do
{
foreach(inout i, c; arr[j..$])
if(‘ ' == c)
break;

// do something and continue
j+=(i+skip);
}while(i != arr.length)


June 08, 2006
In article <e67qth$ugk$1@digitaldaemon.com>, Ameer Armaly says...
>
>
>"BCS" <BCS@pathlink.com> wrote in message news:e67p90$rol$1@digitaldaemon.com...
>>I often find my self doing something like this:
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int j, c; arr)
>> if(' ' == c)
>> {
>> i=j; // copy j out of foreach's scope
>> break;
>> }
>>
>> if(i < arr.length)
>> {
>> arr = arr.dup;
>> // use copy of j
>> foreach(inout c; arr[i..$])
>> if(' ' == c) c = '_';
>> }
>> </code>
>>
>> In this case it would be nice to be able to use a variable in the outer scope as the index in the foreach, e.i.
>>
>> <code>
>> int i
>> char[] arr;
>>
>> foreach(int i, c; arr)
>> if(' ' == c)
>> break;
>>
>> // i keeps the value from the last time through
>> ...
>> </code>
>>
>>
>> Thoughts comments??
>Wouldn't a function return serve a similar if not identical purpose?
>
>
Yes, but that would require putting the foreach in a function. If it needs to access local variables then it needs to be a nested function and therefore could results in a lot of lookup by pointer. Also there is the added function call overhead associated with it. If the code is performance critical all of these are bad things.


June 08, 2006
What's weird to me is if I do this:

    void main()
    {
        int    i;
        char[] arr = "abc def";

        foreach( i, c; arr )
        {
            printf( "%i\n", i );
            if(' ' == c)
                break;
        }
        printf( "\n%i\n", i );
    }

Then the output is:

    0
    1
    2
    3

    0

So the code compiles without a type for i in the foreach, but rather than use the instance of i in the surrounding scope a local value is used instead.  The spec isn't clear on what should happen here, but I would have guessed that the final value displayed would be 3, not 0.


Sean
June 08, 2006
Sean Kelly wrote:
> What's weird to me is if I do this:
> 
>     void main()
>     {
>         int    i;
>         char[] arr = "abc def";
> 
>         foreach( i, c; arr )
>         {
>             printf( "%i\n", i );
>             if(' ' == c)
>                 break;
>         }
>         printf( "\n%i\n", i );
>     }
> 
> Then the output is:
> 
>     0
>     1
>     2
>     3
> 
>     0
> 
> So the code compiles without a type for i in the foreach, but rather than use the instance of i in the surrounding scope a local value is used instead.  The spec isn't clear on what should happen here, but I would have guessed that the final value displayed would be 3, not 0.
> 
> 
> Sean

It creates a new scope, just like for loops:

int i = 5;
for (int i = 0; i < 3; ++i)
	writefln(i); // 0 to 2
writefln(i); // 5

I don't know about the spec's opinion, but this is how it has always worked,
both with for and foreach, and I have a lot of code that relies on this behaviour.

The "inout" suggested elsewhere in the thread by Regan Heath seems like a good solution to me.
June 08, 2006
Deewiant wrote:
> Sean Kelly wrote:
>> What's weird to me is if I do this:
>>
>>     void main()
>>     {
>>         int    i;
>>         char[] arr = "abc def";
>>
>>         foreach( i, c; arr )
>>         {
>>             printf( "%i\n", i );
>>             if(' ' == c)
>>                 break;
>>         }
>>         printf( "\n%i\n", i );
>>     }
>>
>> Then the output is:
>>
>>     0
>>     1
>>     2
>>     3
>>
>>     0
>>
>> So the code compiles without a type for i in the foreach, but rather
>> than use the instance of i in the surrounding scope a local value is
>> used instead.  The spec isn't clear on what should happen here, but I
>> would have guessed that the final value displayed would be 3, not 0.
>>
>>
>> Sean
> 
> It creates a new scope, just like for loops:
> 
> int i = 5;
> for (int i = 0; i < 3; ++i)
> 	writefln(i); // 0 to 2
> writefln(i); // 5

Yes, but my example was equivalent to this (I thought):

    int i = 5;
    for (i = 0; i < 3; ++i)
        writefln(i); // 0 to 2
    writefln(i); // 2

ie, the lack of a type makes the "i=0" an assignment, not a declaration with an initializer.  The i from the surrounding scope is used.  I expected foreach to behave the same way, but apparently it doesn't.


Sean
« First   ‹ Prev
1 2