Are iterators and ranges going to co-exist?

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Wed Jul 21 15:06:11 PDT 2010


Peter Alexander wrote:
> 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 refute this analogy. Matrices and vectors are different beasts - 
there's no obviously defined dot product for a matrix etc. I know there 
are counter-arguments to this, to which I have counter-counter-arguments 
to which I'm sure there are counter-counter-counter arguments and so on, 
so I suggest we continue discussing iterators and not the validity of 
this analogy.

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

Well a pragmatic answer is that you only have ranges in a consistently 
range-based interface.

> Why can't I just pass in the single position I want to insert 
> before? The same applies for insertAfter.

Because D's containers don't define a notion of "a single position".

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

Maybe you want to replace one element with an entire range.


Andrei


More information about the Digitalmars-d mailing list