Jump to page: 1 2
Thread overview
Maybe we don't need foreach ;-)
Oct 31, 2006
Bill Baxter
Oct 31, 2006
Walter Bright
Oct 31, 2006
Bill Baxter
Nov 01, 2006
Burton Radons
Oct 31, 2006
Reiner Pope
Oct 31, 2006
Bill Baxter
Oct 31, 2006
Walter Bright
Oct 31, 2006
Bill Baxter
Oct 31, 2006
Walter Bright
Oct 31, 2006
Bill Baxter
Oct 31, 2006
Bruno Medeiros
Oct 31, 2006
Lionello Lunesu
Oct 31, 2006
Frits van Bommel
Oct 31, 2006
Lionello Lunesu
Oct 31, 2006
Walter Bright
October 31, 2006
Just like some people have said, you can do everything with 'for'.
Well, actually maybe you can.  It occurred to me that foreach and for really don't clash.  One requires two semicolons, the other only one. So instead of a foreach we could have had

  for(a; aggregate)
  {

  }


or if the keyword 'in' had been used for the new construct instead of borrowing from c's ; syntax it would be:

  for(a in aggregate)
  {
     ...
  }

which could quite peacefully coexist with good-ole

  for (int i=0; i<10; i++)
  {
  }

Oh well.  Too much momentum behind foreach and foreach_reverse now, I suppose, to make such a simplification.

--bb
October 31, 2006
Bill Baxter wrote:
> Just like some people have said, you can do everything with 'for'.
> Well, actually maybe you can.  It occurred to me that foreach and for really don't clash.  One requires two semicolons, the other only one. So instead of a foreach we could have had
> 
>   for(a; aggregate)
>   {
> 
>   }

That looks like a syntax error for one used to for loops.

> or if the keyword 'in' had been used for the new construct instead of borrowing from c's ; syntax it would be:
> 
>   for(a in aggregate)
>   {
>      ...
>   }

'in' is already an operator, so that wouldn't work.

> which could quite peacefully coexist with good-ole
> 
>   for (int i=0; i<10; i++)
>   {
>   }
> 
> Oh well.  Too much momentum behind foreach and foreach_reverse now, I suppose, to make such a simplification.

foreach is a fairly well understood term, I think it needs less explanation than a variant on for.
October 31, 2006
Walter Bright wrote:
> Bill Baxter wrote:
>> Just like some people have said, you can do everything with 'for'.
>> Well, actually maybe you can.  It occurred to me that foreach and for really don't clash.  One requires two semicolons, the other only one. So instead of a foreach we could have had
>>
>>   for(a; aggregate)
>>   {
>>
>>   }
> 
> That looks like a syntax error for one used to for loops.

For one used to C for loops, yes.  But Python for loops look like
  for a in aggregate: ...
Bash for loops look like
  for f in list; do ... done

There is certainly precedent for using 'for' synonymously with 'for each'.

>> or if the keyword 'in' had been used for the new construct instead of borrowing from c's ; syntax it would be:
>>
>>   for(a in aggregate)
>>   {
>>      ...
>>   }
> 
> 'in' is already an operator, so that wouldn't work.

It already has multiple duties as a storage type, so that alone shouldn't be an issue.
But I suppose you're right that it won't work here since a standard for loop can start with an Expression, which can contain an 'in'.  So this would require arbitrary lookahead to see if there are any ';''s coming or not.

Anyway, it wouldn't be a problem in a foreach :-).  foreach can only start with ForeachTypeList so there would be no problems with:

   foreach(a in aggregate) { }

as far as I can tell.

>> which could quite peacefully coexist with good-ole
>>
>>   for (int i=0; i<10; i++)
>>   {
>>   }
>>
>> Oh well.  Too much momentum behind foreach and foreach_reverse now, I suppose, to make such a simplification.
> 
> foreach is a fairly well understood term, I think it needs less explanation than a variant on for.

Perhaps.  But we're talking about epsilon vs 2*epsilon in terms of the amount of explanation required.

One thing foreach has going for it is that it makes it feasible to replace the ';' with the 'in' keyword.  :-)

--bb
October 31, 2006
I don't see much reason to change the syntax here, since:
 - it provides no generalizations/abstractions
 - it only saves 4 keys of typing
 - it isn't easier to read; perhaps even *harder* (you don't know whether it is a custom iterator or a 'normal' for loop)
 - Walter's right: it could increase bugs, such as:

     for (char[] key, char[] value; aggregate)

        which looks similar to

     for (char[] key; char[] value; aggregate)

Cheers,

Reiner
October 31, 2006
Reiner Pope wrote:
> I don't see much reason to change the syntax here, since:
>  - it provides no generalizations/abstractions

It generalizes 'for'.

>  - it only saves 4 keys of typing

It's more about saving a keyword in the grammar than saving typing.

>  - it isn't easier to read; perhaps even *harder* (you don't know whether it is a custom iterator or a 'normal' for loop)

Yeh, that's sort of true, but 90% of regular for loops have a ++ or -- or += or .next() in them at the end that make them pretty easy to recognize as regular for loops.  Any for loop that doesn't fit that pattern already takes some scrutiny to figure out.

>  - Walter's right: it could increase bugs, such as:
> 
>      for (char[] key, char[] value; aggregate)
> 
>         which looks similar to
> 
>      for (char[] key; char[] value; aggregate)

That'd be a syntax error.   You cannot declare variables in the second clause of a standard for-loop.  You can only have an Expression there.

But yeh, I'm sure you can cook up some example where you change one comma to a semicolon and both are legal.

Anyway, the real answer is trailing delegates.  This wasn't a serious proposal for change, more just musing on what could have been.  foreach didn't really have to be a keyword, I don't think, that's the only observation I was trying to make.

--bb
October 31, 2006
Bill Baxter wrote:
> But yeh, I'm sure you can cook up some example where you change one comma to a semicolon and both are legal.

	for (a, b; c)
	for (a; b; c)

Not only do they look very, very similar, it is not at all obvious which one was intended.
October 31, 2006
I got so used to foreach in D, I've just ported it to C ;)

namespace D {
template <typename T, int S>
inline size_t length( T (&a)[S] ) { return S; }
// Add overloads for your own containers
}

#define foreach(ELEMENT,ARRAY) \
  for(size_t __L=D::length(ARRAY),__B=0,__I=0; !__B && __I<__L;
assert(__L==D::length(ARRAY)), ++__I ) \
    if (__B = 1) \
      for(ELEMENT = ARRAY[__I]; __B; __B=0) // a break must make the main
loop stop

Don't get too scared; Microsoft's compiler does a great job optimizing that loop. In fact, if you don't use 'break', the second loop will disappear completely. I haven't checked the generated code on other compilers yet.

You use it like this (yes, it's C):

int nums[] = {1,2,3,4};
foreach(int i,nums) { }
foreach(int &i,nums) { i=2; }

L.


October 31, 2006
Walter Bright wrote:
> Bill Baxter wrote:
>> But yeh, I'm sure you can cook up some example where you change one comma to a semicolon and both are legal.
> 
>     for (a, b; c)
>     for (a; b; c)
> 
> Not only do they look very, very similar, it is not at all obvious which one was intended.

Assuming you mean literally a b and c, it's pretty clear it's got to be a foreach that was intended.  There's no reason to stick a variable in either the first or last clause of a standard for.

Here's a example where the intent really isn't obvious:

   for (int a; b;)
   for (int a; b)

Anyway, given that
* I myself have been guilty of using ',' where I meant ';' in for loops,
* 'in' can't be used in place of ';' due to syntactical ambiguities,

I agree that it's safer and better to have foreach separate.

--bb
October 31, 2006
Bill Baxter wrote:
> Assuming you mean literally a b and c, it's pretty clear it's got to be a foreach that was intended.  There's no reason to stick a variable in either the first or last clause of a standard for.

There is if a and b are function names.


> Here's a example where the intent really isn't obvious:
> 
>    for (int a; b;)
>    for (int a; b)
> 
> Anyway, given that
> * I myself have been guilty of using ',' where I meant ';' in for loops,
> * 'in' can't be used in place of ';' due to syntactical ambiguities,
> 
> I agree that it's safer and better to have foreach separate.
> 
> --bb
October 31, 2006
Walter Bright wrote:
> Bill Baxter wrote:
>> Assuming you mean literally a b and c, it's pretty clear it's got to be a foreach that was intended.  There's no reason to stick a variable in either the first or last clause of a standard for.
> 
> There is if a and b are function names.

I see.  I didn't realize this property stuff extended to plain functions too.  I would be strongly inclined to wedgie anyone who made extensive use of that feature.  :-)

--bb
« First   ‹ Prev
1 2