Repost: make foreach(i, a; range) "just work"
Regan Heath
regan at netmail.co.nz
Fri Feb 21 08:41:00 PST 2014
On Fri, 21 Feb 2014 15:35:44 -0000, Jesse Phillips
<Jesse.K.Phillips+D at gmail.com> wrote:
> 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.
Ignore the 3 schemes they were just me thinking about how what I actually
want will affect built in tuple expansion etc.
I want just 1 thing to change (at this time), an index added to foreach
over ranges so that it matches arrays, e.g.
foreach(index, value; range) { }
The code change is likely quite literally just adding an int to the
foreach handler for ranges, passing it to the foreach body, and
incrementing it afterwards. That's it, well, plus the front end code to
bind the variable.
All I am suggesting is that we take what we currently have:
foreach([index, ]value; array) { }
foreach(value; range) { }
foreach(key, value; tuple) { }
and make this possible too:
foreach([index, ]value; range) { }
>>> 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.
No, I was actually suggesting a change here, the compiler would use type
matching not ordering to assign the variables. So because 'v' is a
string, it is bound to the value not the key.
>>> 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.
Thanks! Ok, so how is this working? ahh, ok I think I get it. enumerate
returns a range, whose values are Tuples of index/value where value is
also a tuple so is flattened, and then the whole lot is flattened into the
foreach.
So, while the range foreach only supports:
foreach(value; range) { }
value in this case is a flattened tuple of (index, v1, v2, ...)
Yes?
I had completely forgotten about tuple flattening.
I don't think this affects what I actually want to change, we can have:
foreach(index, value; range) { }
and still flatten tuples into value, you would simply have to provide one
extra variable to get an index.
Make sense?
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list