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

Dukc ajieskola at gmail.com
Tue Aug 13 13:48:48 UTC 2019


On Saturday, 10 August 2019 at 21:42:00 UTC, Manu wrote:

> I tend to hate special-case rules (in this case, loop counters
> behaving differently than function arguments), but I think I'm
> persuaded here.

Not sure what you mean here... example?

> Okay, here's some experiment cases:
>
>   int x = 1;
>   static foreach (i; AliasSeq!(10, x, 20))
>       pragma(msg, __traits(isRef, i));
>
>> false false false
>
> In this case, `i` is an alias. Ref-ness doesn't mean anything 
> here.

I thought that would compile only without the `static` keyword. 
Gotta investigate. If it compiles, I'm going to say it should 
behave exactly as written without the `static` keyword.

Same answer for the rest of examples with tuples.

> Now, there's a different set of cases, where you call static 
> foreach over a not-a-tuple:
>
>   static foreach (i; [10, 20, 30])
>       pragma(msg, __traits(isRef, i));
>
>> false false false
>
> In this case, `i` is not an alias like the previous experiment, 
> it is
> inferred to be `int`.
> Should be the same as `static foreach (int i; ...)`, right?
>
>   static foreach (ref i; [10, 20, 30])
>       pragma(msg, __traits(isRef, i));
>
>> true true true

Yes, these are the cases I meant with `static foreach`. I think 
`[10, 20, 30]` is a rvalue, and if the latter of these two 
examples compiles, it should not.

>
> As above, we could allow this by creating temporaries the same 
> as function arguments... but we've decided not to allow ref 
> iterators from rvalues.
>
>   static foreach (auto ref i; [10, 20, 30])
>       pragma(msg, __traits(isRef, i));
>
>> false false false ??

Yes, exactly what's supposed to happen.

>
> I guess the whole array is an rvalue, so then the loop counter 
> would take copies of the elements?
>
> It gets interesting when you do this:
>
>   int[3] x = [10, 20, 30];
>   static foreach (ref i; x)
>       pragma(msg, __traits(isRef, i));
>
>> true true true

I don't think that compiles. x is not an enum value. But I might 
be wrong, I'll have to recheck this also.

>
> And:
>
>   int[3] x = [10, 20, 30];
>   static foreach (auto ref i; x)
>       pragma(msg, __traits(isRef, i));
>
>> true true true

Same as above. If x was enum, then it should not compile with 
`ref` and should return false false false with `auto ref`.

> TL;DR, your sentence "It should be allowed in static foreach, 
> but with no effect" should be removed, and if you want to 
> detail the expected semantics with `static foreach`, that might 
> be a good idea.

I will check those examples that I thought won't compile do. If 
they do, I'll be more explicit.


More information about the Digitalmars-d mailing list