Jump to page: 1 2
Thread overview
DIP 1010--Static foreach--Formal Review
Jul 10, 2017
Mike Parker
Jul 10, 2017
jmh530
Jul 11, 2017
Timon Gehr
Jul 11, 2017
jmh530
Jul 11, 2017
jmh530
Jul 11, 2017
Daniel N
Jul 12, 2017
Timon Gehr
Jul 11, 2017
Jack Stouffer
Jul 11, 2017
H. S. Teoh
Jul 12, 2017
John Colvin
Jul 12, 2017
Timon Gehr
Jul 12, 2017
Adrian Matoga
Jul 13, 2017
Mike Parker
July 10, 2017
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

July 10, 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.
>
> 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

I have two somewhat related questions.

In the "Generating fields" section, does it have to be a static struct? I see another example with an abstract class with a static for each, but I don't see simpler struct/class examples.

I ask this because it seems like static foreach can be used to provide the same functionality as inout, e.g.

class Foo
{
	static foreach(T; AliasSeq!(int,const(int),immutable(int)))
	{
		void bar(T t)
		{
		}
	}
}


July 11, 2017
On 10.07.2017 20:07, jmh530 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
> 
> I have two somewhat related questions.
> 
> In the "Generating fields" section, does it have to be a static struct? 

No. (They are static structs because they are static structs in Vladimir's code.)

> I see another example with an abstract class with a static for each, but I don't see simpler struct/class examples.
> 
> I ask this because it seems like static foreach can be used to provide the same functionality as inout, e.g.
> 
> class Foo
> {
>      static foreach(T; AliasSeq!(int,const(int),immutable(int)))
>      {
>          void bar(T t)
>          {
>          }
>      }
> }
> 
> 

Yes, this code works and does what you want. (The difference to inout is that you actually get three different implementations and you are able to vary the implementation based on T.)
July 11, 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.
>
> 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?
July 11, 2017
On Tuesday, 11 July 2017 at 07:42:22 UTC, Timon Gehr wrote:
>
> Yes, this code works and does what you want. (The difference to inout is that you actually get three different implementations and you are able to vary the implementation based on T.)

Clearly, this has more power than inout.

I suppose what I'm wondering if it makes inout superfluous. For instance, we should be able to add something like
template Inout(T) { alias Inout = AliasSeq(T, const(T), immutable(T)); }
and use static foreach on it to replicate one of inouts most useful features.

The other major use of inout is something like

class Foo
{
	void bar(int t) inout
	{
	}
}

which I imagine could be replaced now with SetFunctionAttributes, though my method was a little ugly and I don't know if there's a more elegant approach with static foreach.
July 11, 2017
On 7/11/17 10:08 AM, jmh530 wrote:
> On Tuesday, 11 July 2017 at 07:42:22 UTC, Timon Gehr wrote:
>>
>> Yes, this code works and does what you want. (The difference to inout is that you actually get three different implementations and you are able to vary the implementation based on T.)
> 
> Clearly, this has more power than inout.

It's not as good actually. In the mutable form, you can modify the data.

It all depends on if you care about const guarantees or bloat. If you don't and just want to handle all forms, you can use a template (much easier IMO than using static foreach).

> I suppose what I'm wondering if it makes inout superfluous.

I would say no, inout has a very well defined and convenient mechanism to deal with properties on all const flavors of objects. There are many who say templates are good enough, so YMMV. However, nothing so far has successfully implemented the requirement that during the inout function execution, the compiler enforces no mutability.

> The other major use of inout is something like
> 
> class Foo
> {
>      void bar(int t) inout

hm..., this should probably return inout for it to make sense.

>      {
>      }
> }
> 
> which I imagine could be replaced now with SetFunctionAttributes, though my method was a little ugly and I don't know if there's a more elegant approach with static foreach.

There is a way to do it with 'this' template parameter:

int * member;
auto bar(this T)()
{
   return member; // returns const, immutable, or mutable depending on modifier for 'this'
}

Still is bloated into multiple instantiations, and still allowed to mutate for mutable call. Plus it's confusing.

-Steve
July 11, 2017
On Tuesday, 11 July 2017 at 14:23:27 UTC, Steven Schveighoffer wrote:
>
> It's not as good actually. In the mutable form, you can modify the data.
>
[snip]

Clears things up. Thanks.

July 11, 2017
On Monday, 10 July 2017 at 08:53:42 UTC, Mike Parker wrote:
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1010.md

Sorry for not getting in on the original review, but I've submitted a PR for the DIP in regards to formatting.
July 11, 2017
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?

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?

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
July 11, 2017
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


T

-- 
Любишь кататься - люби и саночки возить.
« First   ‹ Prev
1 2