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

Jesse Phillips Jesse.K.Phillips+D at gmail.com
Thu Feb 20 18:34:28 PST 2014


On Thursday, 20 February 2014 at 11:15:14 UTC, Regan Heath wrote:
> I am posting this again because I didn't get any feedback on my 
> idea, which may be TL;DR or because people think it's a dumb 
> idea and they were politely ignoring it :p

I certainly have wanted counts of the range iteration, but I do 
believe it becomes too complex to support and that even if we 
state 'i' is to represent a count and not an index, people will 
still want an index and expect it to be an index of their 
original range even though it makes no possible sense from the 
perspective of iterating over a different range from the original.

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

> Scheme 1)

As Marc said, "ails backwards-compatibility." A change like this 
will never exist if it isn't backwards compatible. There are very 
few changes which will be accepted if backwards compatibility 
isn't preserved.

> Scheme 2)
> However, if a type is given and the type can be unambiguously 
> matched to a single tuple component then do so.
>
> double[string] AA;
> foreach (string k; AA) {} // k is "key"

While probably not common, what if one needed to switch key/value

string[double] AA;

or something similar, the type system no longer helps. But again, 
this seems pretty much uneventful.

> foreach (i, k, v; AA.byPairs.enumerate) {}
> foreach (i, k, v; AA) {} // better

Bringing this back to range iteration:

     foreach(i, v1, v2; tuple(0,1).repeat(10))
         writeln(i, "\t",v1, "\t",v2);

Later the range gets a new value, the foreach would still compile 
but be wrong:

     foreach(i, v1, v2; tuple(0,1,2).repeat(10))
         writeln(i, "\t",v1, "\t",v2);

With enumerate, there is an error.

     foreach(i, v1, v2; tuple(0,1,2).repeat(10).enumerate)
         writeln(i, "\t", v1, "\t", v2);
Error: cannot infer argument types

I don't see enough benefit for making this a language feature.


     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.


More information about the Digitalmars-d mailing list