DIP 1022---foreach auto ref---Community Review Round 2

Dukc ajieskola at gmail.com
Sat Oct 26 14:16:08 UTC 2019


On Friday, 25 October 2019 at 12:09:23 UTC, Timon Gehr wrote:
> - I think it is important that the lines marked (1) and (2) in 
> the code below have equivalent validity:
>
> ---
> struct Iota{
>     int s,e;
>     void popFront(){ s++; }
>     @property bool empty(){ return s>=e; }
>     @property int front(){ return s; }
>     version(ASSIGNABLE_FRONT) @property void front(int i){ s=i; 
> }
> }
>
> void foo(ref int){}
>
> void main(){
>     foo(Iota(0,5).front);      // (1)
>     foreach(ref x;Iota(0,5)){} // (2)
> }
> ---
>
> As far as I can tell, with the current state of the language, 
> this is what this DIP attempts to propose.

Yes, exactly.

> - The DIP claims that "It also proposes that current usages of 
> `ref` may be replaced with `auto ref` to retain the current 
> behavior."
>
> This is not correct:
>
> foreach(ref i;iota(0,5)){ // current behavior:
>     static assert(__traits(isRef,i));
> }
> foreach(auto ref i;iota(0,5)){ // new behavior:
>     static assert(!__traits(isRef,i));
> }

Perhaps it's best to just mention that in the "breaking changes". 
That is probably rare enough to not cause major issues.

>
>
> - The DIP fails to address the following cases:
>
> import std.stdio;
> void main(){
>     foreach(ref x;0..5){ // ???
>         if(x==3) x=5;
>         writeln(x);
>     }
>     foreach(auto ref x;0..5){ // ???
>         if(x==3) x=5;
>         writeln(x);
>     }
> }

Loop A should error, and loop B iterate by copy.

>
> void foo(ref int x){}
> void main(){
>     [1,2,3][1]=2; // currently: error
>     foo([1,2,3][1]); // currently: ok
>     foreach(ref x;[1,2,3]){ // ???
>         x=2;
>     }
>     foreach(auto ref x;[1,2,3]){ // ???
>         x=2;
>     }
> }
>

It could be argued `[1,2,3]` is essentially an enum value, so 
that `foo([1,2,3][1])` should not compile, and to do otherwise is 
a bug. In that case, loop A should error. On the other hand, 
`[1,2,3]` could be seen as a nameless variable in which case loop 
A should compile.

Either way, loop B must compile like loop A if we allow loop A, 
otherwise it must iterate by copy.

Any opinions about how loop A should be treated here? I tend to 
think it should not compile, but I think one could convince me 
otherwise.

> I think both of these should be discussed explicitly.

For that second one, I probably will. For the first one, see my 
reply to Walter's criticism - the example will implicitly explain 
that.

Good points, by the way.




More information about the Digitalmars-d mailing list