March 06, 2014
On Wednesday, 5 March 2014 at 22:54:38 UTC, Andrei Alexandrescu wrote:
> On 3/5/14, 11:40 AM, Tofu Ninja wrote:
>> On Wednesday, 5 March 2014 at 18:58:49 UTC, Andrei Alexandrescu wrote:
>>>
>>> The one difficulty is figuring how to allow for all iterations to stay
>>> in the same scope, yet not have duplicate definitions of the iteration
>>> symbol. Probably worth a DIP. Other than that, we're a go.
>>>
>>> Andrei
>>
>> Do you have an idea of how to solve that? If not I have an idea but it
>> is a little silly and it would introduce a new feature so I would rather
>> wait and hear if there are any other solutions.
>
> My idea revolves around replacing the iteration variable(s) with the respective literal(s) before doing semantic analysis. This is probably unprecedented.
>
> Andrei

Forgive me if this has a real name, but what I think is needed is some kind of partial scope construct. A way to declare a scope for a specific symbol whilst still using it in the outside scope. I think an example would make more sense than me trying to explain it.

partial_scope
{
     /*block A*/
     //Things declared here are available in A and B
     int val = 5;
}
{
     /*block B*/
     //Things declared here are available in B and the outside scope
     int x = val;
}

int y;
y = x; // works
y = val; // fails

Things declared in block A are available in block A and block B. Anything declared in block B would be available in block B and the outside scope. Things declared in block A are not available in the outside scope.

With something like this, each iteration of the static foreach would just be rewritten as a partial_scope with the iterator declared in block A.
March 06, 2014
On 3/5/14, 4:59 PM, Shammah Chancellor wrote:
> Actually, there is static foreach if you are iterating over a tuple.

There's one scope for iteration. We need all iterations to occur in the same scope as the foreach statement.

Andrei


March 06, 2014
On Thursday, 6 March 2014 at 16:58:12 UTC, Andrei Alexandrescu wrote:
> On 3/5/14, 4:59 PM, Shammah Chancellor wrote:
>> Actually, there is static foreach if you are iterating over a tuple.
>
> There's one scope for iteration. We need all iterations to occur in the same scope as the foreach statement.
>
> Andrei

Also grammar currently does not allow it to be used as declaration (which is key use case for me)
March 06, 2014
On 03/05/2014 11:41 PM, deadalnix wrote:
> On Wednesday, 5 March 2014 at 21:54:52 UTC, Timon Gehr wrote:
>> ...
>>
>> static if needs exactly the same thing, currently the following compiles:
>>
>> static if(is(int A)){}
>> A b; // meh
>>
>> It's pretty easy to solve: Just give static if/static foreach it's own
>> scope, but by default forward symbol insertions to the enclosing
>> scope. Symbols introduced by the construct itself are inserted
>> directly into its scope and not forwarded.
>>
>
> I don't think this is the right solution. Spewing error is better
> than overly complicated design.

I don't understand what your point is. Care to elaborate?
March 06, 2014
On 3/6/14, 9:12 AM, Dicebot wrote:
> On Thursday, 6 March 2014 at 16:58:12 UTC, Andrei Alexandrescu wrote:
>> On 3/5/14, 4:59 PM, Shammah Chancellor wrote:
>>> Actually, there is static foreach if you are iterating over a tuple.
>>
>> There's one scope for iteration. We need all iterations to occur in
>> the same scope as the foreach statement.
>>
>> Andrei
>
> Also grammar currently does not allow it to be used as declaration
> (which is key use case for me)

Correct!

Andrei
March 06, 2014
On 03/06/2014 12:35 AM, bearophile wrote:
> Andrei Alexandrescu:
>
>> Walter and I would preapprove implementation of static foreach if and
>> only if a solid DIP comes about.
>
> Some suggestions for a static foreach DIP:
> - It should work at global scope too (I'd like with() to work at global
> scope too).

Of course. static foreach will be both a declaration and a statement.

> - The semantics of "static foreach (x; TypeTuple!(1, 2))" should not
> change, if possible (in alternative it could change a little, but
> eventually become a syntax error).

No. static foreach does not introduce a new scope. "TypeTuple"-foreach does. Deprecating this language feature is not in scope of the 'static foreach' DIP. It's separate, and I'd even argue for not doing it.

> - At first "foreach (x; TypeTuple!(1, 2))"  should give a warning, then
> a deprecation message, and then an error message that "static" is
> required. This makes iteration on type tuples visibly static.

It's not the same thing.

> - "static foreach_reverse (immutable i; 0 .. 10)" could be supported.

Good point.

> - "static foreach (immutable i; iota(1, 10, 2))" should work.
> - Please no tuple unpacking, because this foreach feature should die and
> be replaced by something more general and more correct.
> ...

foreach and static foreach should behave the same in all shared aspects. (Unfortunately, this statement is somewhat messy to formalize.)
March 06, 2014
Timon Gehr:

> No. static foreach does not introduce a new scope. "TypeTuple"-foreach does. Deprecating this language feature is not in scope of the 'static foreach' DIP. It's separate, and I'd even argue for not doing it.

My most basic point in this ER is to require a "static" before "foreach" when you loop on TypeTuples, because the current situation is confusing for newbies and makes D code less explicit:
https://d.puremagic.com/issues/show_bug.cgi?id=4085

Introducing a third type of foreach that is intermediate between the semantucs of the regular foreach and the already present typetuple foreach is ridiculous, will increase the language complexity and will make D and even more confusing for newbies.

Bye,
bearophile
March 06, 2014
Timon Gehr:

> foreach and static foreach should behave the same in all shared aspects. (Unfortunately, this statement is somewhat messy to formalize.)

I am for deprecating unpacking of TypeTuples in foreach. Introducing such unpacking in static foreach just to deprecate it (hopefully a little) later is not wise.

Bye,
bearophile
March 06, 2014
On Thursday, 6 March 2014 at 17:24:07 UTC, Timon Gehr wrote:
> On 03/05/2014 11:41 PM, deadalnix wrote:
>> On Wednesday, 5 March 2014 at 21:54:52 UTC, Timon Gehr wrote:
>>> ...
>>>
>>> static if needs exactly the same thing, currently the following compiles:
>>>
>>> static if(is(int A)){}
>>> A b; // meh
>>>
>>> It's pretty easy to solve: Just give static if/static foreach it's own
>>> scope, but by default forward symbol insertions to the enclosing
>>> scope. Symbols introduced by the construct itself are inserted
>>> directly into its scope and not forwarded.
>>>
>>
>> I don't think this is the right solution. Spewing error is better
>> than overly complicated design.
>
> I don't understand what your point is. Care to elaborate?

Forget about it. I think you aright. I misunderstood your proposal.
March 07, 2014
On 2014-03-06 16:06, bearophile wrote:
> Timon Gehr:
>
>> No. static foreach does not introduce a new scope.
>> "TypeTuple"-foreach does. Deprecating this language feature is not
>> in scope of the 'static foreach' DIP. It's separate, and I'd even
>> argue for not doing it.
>
> My most basic point in this ER is to require a "static" before
> "foreach" when you loop on TypeTuples, because the current situation
> is confusing for newbies and makes D code less explicit:
> https://d.puremagic.com/issues/show_bug.cgi?id=4085
>
> Introducing a third type of foreach that is intermediate between the
> semantucs of the regular foreach and the already present typetuple
> foreach is ridiculous, will increase the language complexity and will
> make D and even more confusing for newbies.
>
> Bye, bearophile

+1