On Sun, 15 Nov 2009 14:47:23 -0500, dsimcha <[email protected]> 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