Repost: make foreach(i, a; range) "just work"

Jesse Phillips Jesse.K.Phillips+D at gmail.com
Fri Feb 21 07:35:44 PST 2014


On Friday, 21 February 2014 at 11:12:54 UTC, Regan Heath wrote:
>  - enumerate is not as flexible as many people seem to think.

Only seeing the enumerate missing the ability to optionally add 
an index, but if you aren't adding an index you don't need 
enumerate.

> On Fri, 21 Feb 2014 02:34:28 -0000, Jesse Phillips 
> <Jesse.K.Phillips+D at gmail.com> wrote:
> I don't understand how this is "complex to support"?  It's 
> simple.  It's a count, not an index unless the range is 
> indexable.  If people are going to expect an index here, they 
> will expect one with enumerate as well - and are going to be 
> equally disappointed.  So, they need to be aware of this 
> regardless.

You've provided 3 schemes to support this feature. This suggest 
there are several "right" ways to bring this into the language, 
while you prefer 1 someone may prefer 3.

At least with enumerate one will need to go to the documentation 
which explains enumerate doesn't provide an index... I haven't 
actually reviewed the docs.

>> I also don't find myself needing to count iterations very 
>> often, and I believe when I do, it is because I want to use 
>> that count as an index (possibly needing to add to some global 
>> count, but I don't need it enough to remember).
>
> The justification for this change is the same as for enumerate.
>
> It is common enough to make it important, and when it happens 
> it's frustrating enough that it needs fixing.

I disagree. Enumerate is satisfactory (since it isn't in Phobos I 
can see it as frustrating).

> For example, I find myself using an index to control loop 
> behaviour, most often for detecting the first and last 
> iterations than anything else.  A counter will let you do that 
> just as well as an index.

I wonder if there is a change to the algorithm which would allow 
you to not need the first/last iteration. I think this is the 
main reason I don't need a count, I've learned different ways to 
solve a problem. Which is beneficial since it leads to chaining 
functions instead of relying on foreach.

> Sure.  I personally find this idea compelling enough to warrant 
> some breakage, it is simple, powerful and extensible and avoids 
> all the issues of optional indexes with tuple expansion.  But, 
> I can see how someone might disagree.

Yes, I understand. But D is at a stage in its life when not every 
little detail can be polished. Believe me, D has other areas 
which need polishing but can't be.

>> string[double] AA;
>>
>> or something similar, the type system no longer helps. But 
>> again, this seems pretty much uneventful.
>
> Perhaps I wasn't clear, this would work fine:
>
> string[double] AA;
> foreach (string v; AA) {} // v is "value"
> foreach (double k; AA) {} // k is "key"
>
> or am I missing the point you're making?

if AA is changed to a double[string], then your value loop 
iterates on keys and your key loop iterates on values.

>>     foreach(i, v1, v2; tuple(0,1).repeat(10).enumerate)
>>         writeln(i, "\t", v1, "\t", v2);
>>
>> This works today! And once enumerate is part of Phobos it will 
>> just need an import std.range to use it.

I tested all my claims about enumerate. You need it to import 
std.traits or else is(Largest(...)) will always be false.


More information about the Digitalmars-d mailing list