opApply Vs. Ranges: What should take precedence?

Steven Schveighoffer schveiguy at yahoo.com
Mon Nov 16 05:41:02 PST 2009


On Sun, 15 Nov 2009 14:47:23 -0500, dsimcha <dsimcha at yahoo.com> wrote:

> I was playing around with dcollections today and it reminded me of a  
> subtle
> unresolved issue.  This has been brought up here before, but always  
> buried
> deep in some other thread.  I think it deserves its own thread for some
> serious debate.
>
> What should take precedence when a class or struct defines both a range
> interface and an opApply with one variable?  My vote is for opApply to  
> take
> precedence for the following reasons:
>
> 1.  In general, if someone defines a range interface, and then also  
> defines an
> opApply interface, they probably have a good reason for doing so, since  
> ranges
> provide a superset of opApply functionality.

This is only the case where ranges *can* implement foreach.  There are  
other reasons for opApply, for instance overloading, or having multiple  
indexes.

> 2.  Some things can't be iterated over as efficiently w/o control of the  
> call
> stack.  For example, iterating over trees w/ control of the call stack  
> is easy
> and efficient.  Iterating without control of the call stack requires a  
> heap
> allocation for an explicit stack.

Hm... I disagree here.  My Tree implementation iterates over all the  
elements without recursion.

To answer the original question -- opApply should be chosen, and this is  
not debatable.  There is only *one* purpose for opApply -- to hook onto  
foreach.  If you defined both opApply and equivalent range functions and  
range functions where chosen first, opApply would be wasted code.

If you want to debate whether opApply should even exist anymore, that is a  
valid debate, but I think that ranges need to be much more flexible in  
terms of foreach before that happens.  I don't think ranges will ever be  
useful for defining foreach on an interface.

-Steve



More information about the Digitalmars-d mailing list