Super-dee-duper D features

Bruno Medeiros brunodomedeiros+spam at com.gmail
Thu Feb 15 04:22:30 PST 2007


Andrei Alexandrescu (See Website For Email) wrote:
> 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.
> 

How about just simply:

   auto two = InterleavedInterator (x, y);
   foreach (x; two) { ... }
   foreach (a; two.Project(0)) { ... } // fetch the first iterator
   foreach (b; two.Project(1)) { ... } // fetch the second iterator

One of the two last foreach's won't execute a cicle because there is no 
data.

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

Maybe, but how does your multi foreach proposal helps at all? (see below)

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

I din't understand the above. Did you mean 'y' instead of one of those 'x' ?

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D



More information about the Digitalmars-d mailing list