Super-dee-duper D features

kris foo at bar.com
Tue Feb 13 19:14:59 PST 2007


Andrei Alexandrescu (See Website For Email) wrote:
> kris wrote:
> 
>> 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.
>>>
>>> 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
>>
>>
>> If x, y, & z are of differing type, then I'd agree.
> 
> 
> If they are of the same type and in an arbitrarily large numbers (x1, 
> x2, x3...), we start talking about cutting through some sort of a matrix 
> or manifold, which is an entirely different business.

So if we did have a language-based iterator (which was a hot topic 
recently), it might take the form of a generator?

[snip]



More information about the Digitalmars-d mailing list