Overriding iteration

Magnus Lie Hetland magnus at hetland.org
Fri Mar 4 10:56:50 PST 2011


On 2011-03-04 19:06:34 +0100, Jonathan M Davis said:

> On Friday, March 04, 2011 09:13:34 spir wrote:
>> On 03/04/2011 05:43 PM, Steven Schveighoffer wrote:
[snip]
>> opApply should work but it is supposed to be slower.
>> Defining range primitives directly on the object/container cannot work as
>> of now, unfortunately, because of a pair of bugs (conflicts in formatValue
>> template definitions between struct/class on one hand and ranges on the
>> other).
> 
> You don't _want_ range primitives directly on the container. That would mean
> that everything in your container goes away when you process it.

That was the point of my original question, yes :) In TDPL, where 
Andrei discusses overloading foreach, he has two main examples -- one 
using opApply, and one using such a self-destructive container. I think 
(as I said in my post) that what saves that list is that it's a struct, 
so it's copied by the initial assignment of the foreach statement.

> You _want_ to have a separate type which is a slice of our container 
> and has the range primitives.

Exactly. That was what I was asking for.

> 
> Now, it could very well be that
> 
> foreach(v; container)
> 
> should be calling opSlice on the container, allowing you to feed the container
> to foreach directly instead of having to slice it yourself
> 
> foreach(v; container[])
> 
> but that's just syntactic sugar.

Sure. And judging from the other responses (and from TDPL), the fact 
that this doesn't currently work is just a bug.

> You don't want to actually treat your container like a range. Ranges 
> should be slices of containers, not containers themselves.

Well, it would still be nice to have things be consistent -- and in 
order for the opSlice approach to be consistent with the opApply 
approach (so a client needn't know how iteration is implemented for a 
given container), it seems reasonable to me to have foreach directly 
run on a slice of your container (i.e., implicitly calling []). But as 
this seems to be the way it is (save for the current bug), I guess it's 
sort of a moot point.

I certainly agree with your point, though. In Python, too, iterators 
(i.e., ranges) and iterables (i.e., containers) are separate concepts. 
You can iterate over an iterable, and the loop then automatically 
extracts an iterator. As this is The Way to Go, it makes sense to me 
that it's automatic/implicit.

-- 
Magnus Lie Hetland
http://hetland.org



More information about the Digitalmars-d-learn mailing list