Maybe we don't need foreach ;-)

Burton Radons burton-radons at smocky.com
Wed Nov 1 12:08:26 PST 2006


Bill Baxter wrote:
> 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'.

Who is more likely to move to D - a C/C++ programmer who also knows 
Python/Bash, or a dedicated Python or Bash programmer?

>>> 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.

Arbitrary lookahead is no problem for D (it has to do this anyway, a 
lot, and this is a good thing as it's more important for a language to 
be comprehensible to the user, and minimise redundant information, than 
it is for it to be simple to parse), and is makes logical sense, as it 
iterates over all "a" which are in "aggregate". For example:

     where (uint a; a < 100) // Iterate from 0 to 99.
     where (a; a >= 0 && a < 100 && a % 2) // Iterate over every odd 
value from 0 to 99.
     where (a; a in list1 && a in list2) // Set intersection.
     where (a; a in list1 || a in list2) // Set union.
     where (a; a in list1 && a !in list2) // Set difference.

     auto list3 = where (a; a in list1 && a in list2); // Wee!

This is pretty easy to do terribly, somewhat harder to do usefully, very 
hard to do intelligently, and incomprehensibly hard to do at peak 
optimisability in all cases. I'm not proposing it as a D feature, it's 
very much not in its style and it's something you'd spend twenty years 
progressively optimising, but it would be fun to have these kinds of 
advanced data-processing features in a fast language. So long as we're 
in fantasy-land:

     where (a; 0 <= a < 100)

Ah, that's better. C's idea that logical operations belong on the same 
continuum as equations is so very, very 60s. And if we're no longer 
working with such outdated logic:

     where (a; a in (list1 && list2));

Makes sense to me.



More information about the Digitalmars-d mailing list