random access-range without lower-power range kinds?

Jonathan M Davis jmdavisProg at gmx.com
Tue Dec 14 00:44:17 PST 2010


On Tuesday 14 December 2010 00:09:33 spir wrote:
> Hello,
> 
> It seems impossible to define a random-access range (opIndex + length)
> alone. In fact, I cannot have it used by the language. Am I missing
> something? Random-access looks enough to provide fonctionality for both
> input and bidirectional ranges without any additional method. "Lowering"
> for forward iteration means I guess ;-) for (uint i=0 ; i < coll.length ;
> i++) {
> 	    element = coll[i];
> 	    doSomethingWith(element);
> 	}
> What is the reason for requiring methods of lower-power range types to be
> defined? (This makes 5 methods!)

opIndex() is only used for random access, not iteration. front and popFront() 
are necessary for forward iteration and back and popBack() are necessary for 
backward iteration. So, anything that's going to iterate, needs those functions 
which allow for iteration. Yes, it is conceivable that opIndex() could be used 
to give you iteration, but ranges don't use it that way. It's more complicated 
than using front, popFront(), etc. And if opIndex() could be used for iteration, 
then functions would have to worry about yet another way to iterate.

Think about it for a moment. If you have an algorithm that takes an arbitrary 
ForwardRange, that means that it _must_ have front and popFront(). Having 
opIndex() wouldn't make a range a forward range. If it did, any function using a 
forward range would have to worry about figuring out whether the given forward 
range implemented front and popFront(), or whether it used opIndex(). On top of 
that, opIndex isn't enough to iterate in the fashion that ranges do anyway. An 
opSlice() which took indices would be needed. Otherwise, there's no way to pop 
the front.

Remember that ranges are defined by _Phobos_, not the compiler. There is no 
lowering involved. True, foreach recognizes the ForwardRange primitives, but the 
compiler doesn't lower range functions to anything else. They're called 
directly. At most, it inlines them.

If you can define opIndex() for a type, then it should be straightforward to 
implement the necessary functions for ForwardRange and BidirectionalRange. A 
type is a particular type of range because it implements the functions for that 
range type, not because it _could_ do so or because other functions that it has 
_could_ be used to implement the appropriate range functions. It must have those 
exact functions or it isn't that type of range.

- Jonathan M Davis


More information about the Digitalmars-d-learn mailing list