July 11, 2017
On 7/11/17 7:21 PM, H. S. Teoh via Digitalmars-d wrote:
> On Tue, Jul 11, 2017 at 07:18:51PM -0400, Steven Schveighoffer via Digitalmars-d wrote:
> [...]
>> 3. The only controversial part I see is that `break` doesn't break
>> from the foreach loop. While I agree with the reasoning, and support
>> that concept, the truth is we currently have a "poor man's" static
>> foreach using a foreach over a tuple, and that DOES break from the
>> loop.
> 
> This is a false impression.  It actually does not break from the loop,
> but inserts a break in the generated code, and continues to unroll the
> rest of the loop.  It's only at codegen that the subsequent iterations
> are detected as dead code and elided. See:
> 
> 	https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time#.22static.22_foreach_does_NOT_interpret_break_and_continue

Yes, I know that it still generates all the code, but the break is still interpreted as breaking out of the loop. Timon's proposal says it "does not interact with break", so I interpret that as meaning it should break out of whatever construct is surrounding the loop, not the loop itself.

Currently this:

foreach(j; 0 .. 2)
foreach(i; AliasSeq!(0, 1))
{
    writeln(i);
    static if(i == 0)
      break;
}

will print
0
0

Whereas with my understanding, this:

foreach(j; 0 .. 2)
static foreach(i; 0 .. 2)
{
    writeln(i);
    static if(i == 0)
       break;
}

would print
0

This seems too confusing.

-Steve
July 12, 2017
On 12.07.2017 01:18, Steven Schveighoffer wrote:
> On 7/10/17 4:53 AM, Mike Parker wrote:
>> As promised, since there has been zero feedback on DIP 1010, "Static foreach", in either the Draft or Preliminary review rounds, I'm going to skip the normal two-week feedback cycle on the Formal review. If there are no major criticisms or objections raised in this thread, then sometime on Thursday of this week I'll send Walter & Andrei an email kicking off the decision process.
>>
>> So, if you have any thoughts on the DIP, now is the time to express them.
>>
>> Thanks!
>>
>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1010.md
>>
> 
> A few things:
> 
> 1. I can't wait for this to get in. I'm anticipating success :)
> 
> 2. I see no point in having foreach(enum i; 0.. 3) when static foreach(i; 0 .. 3) works just fine?
> ...

foreach(enum i; 0..3) does not currently compile and is not proposed in this DIP, but it would be useful for the case where you need an unrolled foreach loop.

> 3. The only controversial part I see is that `break` doesn't break from the foreach loop. While I agree with the reasoning, and support that concept, the truth is we currently have a "poor man's" static foreach using a foreach over a tuple, and that DOES break from the loop.
> 
> For instance:
> 
> size_t idx;
> switch(someval)
> {
>     case something:
>        foreach(v; AliasSeq!(1, 2, 3))
>        {
>            if(shouldBreak(v))
>                break; // today, this jumps to moreProcessing() line
>        }
>        moreProcessing();
>        break;
> }
> 
> If I replaced foreach with static foreach(v; 1 .. 4), it now breaks out of the switch?
> ...

Yes.

> As much as I would rather see the proposed behavior, I feel it's too confusing given the existing foreach behavior. I think in this case, you have to require a break label.
> 
> A possible deprecation path:
> 
> 1. In the case where "static foreach" is inside another construct that allows breaking, require a break label. However, foreach over a tuple would continue to exhibit today's behavior.
> 2. print warning message for foreach over a tuple that contains a break without a label. Warn users that a future version will not allow breaking from the foreach.
> 3. disallow breaking out of the foreach directly (i.e. jumping to the closing brace of the loop), even if there is a label (you can surround foreach with a do{} while(false) if you need this behavior).
> 4. Remove the requirement for labeling. Both static foreach and foreach on a tuple do not break from the loop construct.
> 
> -Steve

I don't see why for foreach, break behaviour should depend on the aggregate, that is much more confusing. static foreach is not a loop with a loop body, it generates multiple versions of the given code. There is no reason why static foreach and foreach should have "the same" (whatever that even means!) behaviour with respect to runtime break, and if it is really considered too confusing, static foreach should just always require an explicit label. (But this is painful for me to implement, as it is unnatural.)
July 12, 2017
On Tuesday, 11 July 2017 at 23:50:26 UTC, Steven Schveighoffer wrote:
> On 7/11/17 7:21 PM, H. S. Teoh via Digitalmars-d wrote:
>> On Tue, Jul 11, 2017 at 07:18:51PM -0400, Steven Schveighoffer via Digitalmars-d wrote:
>> [...]
>>> 3. The only controversial part I see is that `break` doesn't break
>>> from the foreach loop. While I agree with the reasoning, and support
>>> that concept, the truth is we currently have a "poor man's" static
>>> foreach using a foreach over a tuple, and that DOES break from the
>>> loop.
>> 
>> This is a false impression.  It actually does not break from the loop,
>> but inserts a break in the generated code, and continues to unroll the
>> rest of the loop.  It's only at codegen that the subsequent iterations
>> are detected as dead code and elided. See:
>> 
>> 	https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time#.22static.22_foreach_does_NOT_interpret_break_and_continue
>
> Yes, I know that it still generates all the code, but the break is still interpreted as breaking out of the loop. Timon's proposal says it "does not interact with break", so I interpret that as meaning it should break out of whatever construct is surrounding the loop, not the loop itself.
>
> Currently this:
>
> foreach(j; 0 .. 2)
> foreach(i; AliasSeq!(0, 1))
> {
>     writeln(i);
>     static if(i == 0)
>       break;
> }
>
> will print
> 0
> 0
>
> Whereas with my understanding, this:
>
> foreach(j; 0 .. 2)
> static foreach(i; 0 .. 2)
> {
>     writeln(i);
>     static if(i == 0)
>        break;
> }
>
> would print
> 0
>
> This seems too confusing.
>
> -Steve

break inside a case inside a static foreach inside a switch is an interesting case for this sort of reasoning
July 12, 2017
On 11.07.2017 09:50, Daniel N wrote:
> On Monday, 10 July 2017 at 08:53:42 UTC, Mike Parker wrote:
>> As promised, since there has been zero feedback on DIP 1010, "Static foreach", in either the Draft or Preliminary review rounds, I'm going to skip the normal two-week feedback cycle on the Formal review. If there are no major criticisms or objections raised in this thread, then sometime on Thursday of this week I'll send Walter & Andrei an email kicking off the decision process.
>>
>> So, if you have any thoughts on the DIP, now is the time to express them.
>>
>> Thanks!
>>
>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1010.md
> 
> how is __local handled with nested static foreach?

The following code works:

---

static foreach(i;0..4){
    static if(i) __local alias outerPrevious = __previous;
    static foreach(j;0..4){
        static if(i&&j){
            pragma(msg, outerPrevious.i," ",__previous.j);
        }
    }
}
---


It prints:

---
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
---

(However, note that DIP 1010 does not propose adding __local to the language.)
July 12, 2017
On 7/12/17 4:23 AM, Timon Gehr wrote:
> On 12.07.2017 01:18, Steven Schveighoffer wrote:
>> On 7/10/17 4:53 AM, Mike Parker wrote:
>>> As promised, since there has been zero feedback on DIP 1010, "Static foreach", in either the Draft or Preliminary review rounds, I'm going to skip the normal two-week feedback cycle on the Formal review. If there are no major criticisms or objections raised in this thread, then sometime on Thursday of this week I'll send Walter & Andrei an email kicking off the decision process.
>>>
>>> So, if you have any thoughts on the DIP, now is the time to express them.
>>>
>>> Thanks!
>>>
>>> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1010.md
>>>
>>
>> A few things:
>>
>> 1. I can't wait for this to get in. I'm anticipating success :)
>>
>> 2. I see no point in having foreach(enum i; 0.. 3) when static foreach(i; 0 .. 3) works just fine?
>> ...
> 
> foreach(enum i; 0..3) does not currently compile and is not proposed in this DIP, but it would be useful for the case where you need an unrolled foreach loop.

It's in the DIP, regardless of whether it's critical to the acceptance of the DIP. As it's something on the table for W&A to look at, I wanted to voice my opinion on it.

> I don't see why for foreach, break behaviour should depend on the aggregate, that is much more confusing.

Perhaps. My point of view is that I'm generally using foreach over a tuple to generate switch cases. I always think that the break is going to apply to the switch statement, and it gets me every time. In fact, in writing this post, I just found a (harmless?) bug in my code:

switch(str)
{
   foreach(n; names)
   {
       case n:
          ...
          break;
   }
   default:
        break;
}

It's harmless because the default case does nothing. But it certainly isn't what I should have written!

I think of foreach over a tuple as separate from foreach over a runtime type. To me, it's already a different syntax and more akin to static foreach. One may argue that static foreach looks just like foreach, and so all of them should behave the same.

> static foreach is not a loop with a loop body, it generates multiple versions of the given code. There is no reason why static foreach and foreach should have "the same" (whatever that even means!) behaviour with respect to runtime break, and if it is really considered too confusing, static foreach should just always require an explicit label. (But this is painful for me to implement, as it is unnatural.)

From a user perspective, whether I reach for one tool or the other, the behavior shouldn't be subtly different. If I'm looking for a tool to unroll loops, I can use foreach with a tuple, or static foreach. Both should behave the same.

Perhaps the deprecation path should include a removal of straight foreach over a tuple working (use static foreach explicitly). This would make the distinction even more obvious.

-Steve
July 12, 2017
On Wednesday, 12 July 2017 at 10:57:37 UTC, Steven Schveighoffer wrote:
> Perhaps the deprecation path should include a removal of straight foreach over a tuple working (use static foreach explicitly). This would make the distinction even more obvious.

I'd also vote for gradual removal of foreach over a tuple. It would be one less awkward moment when teaching D.


July 13, 2017
On Monday, 10 July 2017 at 08:53:42 UTC, Mike Parker wrote:
> As promised, since there has been zero feedback on DIP 1010, "Static foreach", in either the Draft or Preliminary review rounds, I'm going to skip the normal two-week feedback cycle on the Formal review. If there are no major criticisms or objections raised in this thread, then sometime on Thursday of this week I'll send Walter & Andrei an email kicking off the decision process.
>

Thanks for all the feedback. I don't see anything that is a blocker from moving forward, so I'll cut it off here and move along.

1 2
Next ›   Last »