Repost: make foreach(i, a; range) "just work"

Steven Schveighoffer schveiguy at yahoo.com
Fri Feb 21 06:29:37 PST 2014


On Fri, 21 Feb 2014 06:21:39 -0500, Regan Heath <regan at netmail.co.nz>  
wrote:

> On Thu, 20 Feb 2014 17:09:31 -0000, Steven Schveighoffer  
> <schveiguy at yahoo.com> wrote:
>
>> On Thu, 20 Feb 2014 11:07:32 -0500, Regan Heath <regan at netmail.co.nz>  
>> wrote:
>>
>>> Only if the compiler prefers opApply to range methods, does it?
>>
>> It should. If it doesn't, that is a bug.
>>
>> The sole purpose of opApply is to interact with foreach. If it is  
>> masked out, then there is no point for having opApply.
>
> Thanks.
>
> So, if we had this support which I am asking for:
>
> 	foreach(index, value; range) { }
>
> And, if someone adds opApply to that range, with a different type for  
> the first variable then an existing foreach (using index, value) is  
> likely to stop compiling due to type problems.
>
> This seems acceptable to me.

I think any type that does both opApply and range iteration is asking for  
problems :) D has a nasty way of choosing "all or nothing" for overloads,  
meaning it may decide "this is a range" or "this is opApply", but if you  
have both, it picks one or the other.

I'd rather see it do:

1. can I satisfy this foreach using opApply? If yes, do it.
2. If not, can I satisfy this foreach using range iteration?

This may be how it works, I honestly don't know.

> There is an outside chance it might keep on compiling, like if 'i' is  
> not used in a strongly typed way, i.e. passed to a writefln or similar.   
> In this case we have silently changed behaviour.
>
> Is this acceptable?

Adding opApply is changing the API of the range. If the range does  
something different based on whether you use the range interface or  
opApply, then this is a logic error IMO.

The easiest thing is to just not use opApply and range primitives together  
:) One separation I like to use in my code is that you use opApply on a  
container, but range primitives on a range for that container. And a  
container is not a range.

-Steve


More information about the Digitalmars-d mailing list