Iterators for D
Walter Bright
newshound at digitalmars.com
Mon Nov 6 15:20:37 PST 2006
Bill Baxter wrote:
> Walter Bright wrote:
>> It's becoming increasingly obvious that D needs iterators. While
>> opApply is far better for some kinds of iteration (such as
>> recursively traversing a directory), iterators are more efficient in
>> some cases, and allow for things that opApply makes difficult.
>>
>> So hear are the design goals:
>>
>> 1) Works with dynamic and stat arrays
>
> How about pointers (unknown length arrays)?
> int *some_numbers;
>
> Is it required that a pointer be a valid iterator?
> I.e. should it be possible to have this template function:
>
> print_all(some_numbers, some_numbers+theLength);
>
> Or will that case require a wrapper object that contains theLength?
>
> auto iter = PointerIterator(some_numbers, theLength);
> print_all(iter);
It's simpler than that. Pointers can be converted to arrays:
auto array = some_numbers[0 .. theLength];
and then you can get the iterator.
>> 2) Doesn't need to work with associative arrays
> Why not? Do you mean it doesn't need to because you can just iterate
> over keys or values?
Because that falls into my big complaint with iterators - there's no way
to efficiently 'linearize' a binary tree. Might as well just iterate
over the keys or values.
> That's like C++'s way. Iterator is basically a generalized pointer.
Yes.
> The other proposal is more like Java/Python/C#'s way, where the iterator
> is like a pointer that knows it's own limits.
> The Java/Python/C# way would definitely work in D. I'm not sure about
> the C++ way working for D because, in practice, references and
> dereferencing get used pretty heavily there. On the other hand
> Java/Python/C# were designed without real templates.
I think the C++ like way will be a lot more efficient, and I think it
will work. Reference types are not needed.
> One of the major design goals for C++ was that for a basic array a
> regular pointer should be a valid iterator. Thus the iterator cannot
> know where it's own end() is, because a pointer does not have such
> knowledge. But aside from cute demos on SGI's STL web page where
> algorithms are applied to plain arrays using pointers, I've never seen
> that sort of thing used in the real world. You almost always use a
> std::vector or std::list or something besides a raw array. So pointer
> equivalence seems to be pretty useless to me. Even moreso with D. In
> the rare case you need to work with raw pointers, you can always make an
> iterator wrapper.
I think it'll work fine, since pointers can be easily converted to
dynamic arrays (see above).
> On the plus side for C++ style:
> * iterators are lightweight (just one size_t/pointer in most cases)
> * algorithms and methods all take begin/end pairs making things uniform.
> Minuses
> * Iterators are dumb and error prone and easily go out of bounds
> * algorithms all require begin/end pairs making things cumbersome
>
> I think the minuses outweigh the plusses.
> But maybe it's useful to take one concrete example: A generic mergesort
> or quicksort algorithm.
>
> In C++ recursive calls just pass the limits of the range to the children
> mergesort(begin, end)
> {
> ...
> mergesort(begin, (end-begin)/2);
> mergesort((end-begin)/2, end);
> }
> It's very efficient.
>
> In the iterator-is-object approach I'm not sure how that works.
> If all you've got is .next() or .hasNext() I'm not sure what you're
> supposed to do to create an iterator over half the range represented by
> the original iterator.
Iterators can be any type, not just objects, that support [], ++, +=, and =.
>> foreach loops will not be able to have a 'key' parameter.
> Don't understand that one.
What's the key for an unknown iterator type?
More information about the Digitalmars-d
mailing list