Are iterators and ranges going to co-exist?

Peter Alexander peter.alexander.au at gmail.com
Wed Jul 21 14:39:38 PDT 2010


On 21/07/10 6:33 PM, Andrei Alexandrescu wrote:
> Peter Alexander wrote:
>> == Quote from Walter Bright (newshound2 at digitalmars.com)'s article
>>> If some algorithms used ranges and others used iterators, the
>> poor programmer
>>> would find himself then obliged to implement both interfaces for
>> each container.
>>
>> This makes no sense.
>>
>> I don't understand why you see ranges and iterators as conflicting
>> concepts. The cursors/iterators are for referring to individual
>> elements, and ranges are for specifying iterations over a sequence.
>>
>> There aren't two competing interfaces here. If your interface
>> requires a range of elements, you use a range. If it only needs a
>> single element, you use a cursor.
>>
>> For example, sort would always take a range, as it is sorting a
>> range, not a single element. I *do not* propose that we start
>> writing sort(Iter begin, Iter end) as that is much less flexible
>> than a range, and as you say, it is much harder to validate.
>>
>> An example of an algorithm that would take a cursor is
>> insertBefore. There is no reason for it to accept a range, because
>> you are not traversing elements. You just want to insert something
>> before some single point in the range.
>
> This contradicts the assertion that there's no competition between
> iterators and ranges. Clearly they share at least some turf. Though I
> agree "insert before this given element" is sensible, I don't think
> "insert before this range" is not. Besides, with ranges the notion is
> easier to generalize to "insert after this range" and "replace this
> range with another range". Arguably "insert after this one element" and
> "replace this one element with a range" are less general.
>
> There are benefits to having cursors. There are also disadvantages:
> interfaces and implementations get bloated, users get aggravated,
> documentation gets thicker, conceptual overhead rises, design options
> multiply without necessity ("should I provide replace with one iterator
> in addition to replace with a range?"), writing code becomes more
> painful ("heck, I need a range here but I only have an iterator (or vice
> versa), I need to insert this extra construct here to build the other")
> etc. etc. I understand you want to advocate iterators so you chose to
> not discuss the disaadvantages, but any plan that would ignore them
> would not be complete.

Well, yes, you could say they share some turf, but that's common when 
one can be defined in terms of the other. e.g.

   double norm(Matrix m);
   double norm(Vector v);

Here, vectors are just special cases of matrices, and the matrix version 
will handle norms of vectors just fine. norm(Matrix) is undeniably more 
general. Yet, every linear algebra library I've seen would provide both 
of these, because it's inconvenient (and unintuitive) to have to write

   norm(Matrix(myVector));

I also find it unintuitive to write insertBefore(Range). Why is it 
asking me for a range when it's going to ignore everything but the first 
element? Why can't I just pass in the single position I want to insert 
before? The same applies for insertAfter.

In the case of replacing ranges with other ranges, I don't think there 
is any need for a cursor version. If you want to replace a cursor, you 
just dereference and write to it. Having a function to do that would be 
totally unnecessary.


More information about the Digitalmars-d mailing list