Super-dee-duper D features

Andrei Alexandrescu (See Website For Email) SeeWebsiteForEmail at erdani.org
Tue Feb 13 18:21:40 PST 2007


Bill Baxter wrote:
> kris wrote:
>> kris wrote:
>>> Bill Baxter wrote:
>>>
>>>> Frits van Bommel wrote:
>>>>
>>>>> By the way, would the new loop syntax allow more than two 
>>>>> collections to be simultaneously iterated?
>>>>
>>>>
>>>>
>>>> Whoa!  I certainly hope so.  It hadn't even occurred to me that 
>>>> Andrei might mean this syntax can only be used for just two 
>>>> collections.  If that's the case then ... ick.
>>>>
>>>> --bb
>>>
>>>
>>> InterleavedIterator does multiple collections via using multiple 
>>> instances of InterleavedIterator. It's simple to use, and only needs 
>>> to be written once. Would be better to implement some basic iterator 
>>> needs than to introduce some tricky new syntax?
>>>
>>> - Kris
>>
>>
>> Should have given an example. Simple case with 2 entities:
>>
>> auto two = InterleavedInterator (x, y);
>> foreach (x; two) ...
>>
>> more than 2:
>>
>> auto three = InterleavedInterator (two, z);
>> foreach (x; three) ...
> 
> Should have also mentioned where one can find this mythical 
> InterleavedIterator.

The issue with such a multi-iterator is that it makes it easier to make 
errors, and harder to write efficient and correct code that's statically 
verifiable.

I'm not sure when the interleaved iterator stops iterating, but there 
are two possibilities, none of which is satisfactory:

1. Stop after the shortest of the two collections is done. Then user 
code must query the state of the iterator after the loop to figure what 
extra work is to be done:

auto two = InterleavedInterator (x, y);
foreach (x; two) { ... }
if (two.MoreData(0)) {
   auto back2one = two.Project(0); // fetch the first iterator
   foreach (x ; back2one) { ... }
} else if (two.moreData(1)) {
   ... same (or)deal ...
}

This is way more work than there should.

2. Stop after the longest of the two collections is done. Then user code 
must ensure _at each step_ that both iterators have meaningful data:

auto two = InterleavedInterator (x, y);
foreach (x; two) {
   if (two.HasData(0)) { ... }
   else { ... only the second iter has data ... }
}

This is unclear, verbose, and probably suboptimal.

The scoping of foreach links the scope of the variables with their 
validity range, which rules out a class of possible errors entirely:

foreach (x ; c1) (y ; c2) (z ; c3) {
   ... x, y, z syntactically accessible _and_ valid ...
}
continue foreach (x, z) {
   ... x is both invalid _and_ syntactically inaccessible ...
}

As I mentioned in a different post, the fact that there are 
combinatorial potential sub-foreach statements is a non-issue.


Andrei



More information about the Digitalmars-d mailing list