March 05, 2014
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.
March 05, 2014
Andrei Alexandrescu:

> Doesn't enable anything.

Right, on the other hand a switch offers code more DRY compared to nested static ifs, and this part of the point of having a dynamic switch too. And the cognitive cost for a D programmer to remember what is a "static switch" is small (even if you inevitably need "static final switch" too if you create a "static switch"). I have never opened an enhancement request on this because the need for a static switch is not strong, but it's not zero.


> There'd be a ton more juice in a static foreach; it would enable a lot of great idioms. We should pursue that instead.

> Probably worth a DIP. Other than that, we're a go.

So do you like to tag this issue as pre-approved? (The gist of this ER is that even an arbitrarily partial implementation of a static foreach is better than having none at all):
https://d.puremagic.com/issues/show_bug.cgi?id=4085

Bye,
bearophile
March 05, 2014
On Wednesday, 5 March 2014 at 12:51:23 UTC, Dominikus Dittes Scherkl wrote:
> T opOpAssign(string op, T)(T x) if(op=="+" || op=="-" || op=="*" || op=="/" || op=="%" || op=="^^" || op=="&" || op=="|" || op=="^" || op=="<<" || op==">>" || op==">>>")
> {
>    static switch(op)
>    {
>    case "+":
>    case "-":
>       ...
>       break;
>    case "*":
>       ...
>    }
> }
>
> would look much better than
>
> {
>    static if(op=="+" || op == "-")
>    {
>       ...
>    }
>    else static if(op == "*")
>    {
>       ...
>    }
>    else
>    {
>       ...
>    }
> }

You can simply make it different overloads:

T opOpAssign(string op, T)(T x) if(op=="+" || op=="-")
{
   ...
}

T opOpAssign(string op, T)(T x) if(op=="*" || op=="/" || op=="%")
{
  ...
}

etc.
March 05, 2014
On 03/05/2014 07:58 PM, Andrei Alexandrescu wrote:
> On 3/5/14, 10:45 AM, Dicebot wrote:
>> On Wednesday, 5 March 2014 at 18:39:08 UTC, Andrei Alexandrescu wrote:
>>> Doesn't enable anything. There'd be a ton more juice in a static
>>> foreach; it would enable a lot of great idioms. We should pursue that
>>> instead.
>>>
>>> Andrei
>>
>> Btw, are there any unexpected design difficulties with static foreach?
>> Or it is just waiting for someone to do the pull request?
>
> 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.

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.

> Probably worth a DIP. Other than that, we're a go.
>
> Andrei
>

I will create it this weekend if nobody beats me to it.
March 05, 2014
On Wednesday, 5 March 2014 at 21:54:52 UTC, Timon Gehr wrote:
> On 03/05/2014 07:58 PM, Andrei Alexandrescu wrote:
>> On 3/5/14, 10:45 AM, Dicebot wrote:
>>> On Wednesday, 5 March 2014 at 18:39:08 UTC, Andrei Alexandrescu wrote:
>>>> Doesn't enable anything. There'd be a ton more juice in a static
>>>> foreach; it would enable a lot of great idioms. We should pursue that
>>>> instead.
>>>>
>>>> Andrei
>>>
>>> Btw, are there any unexpected design difficulties with static foreach?
>>> Or it is just waiting for someone to do the pull request?
>>
>> 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.
>
> 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.
March 05, 2014
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
March 05, 2014
On 3/5/14, 1:54 PM, Timon Gehr wrote:
> On 03/05/2014 07:58 PM, Andrei Alexandrescu wrote:
>> On 3/5/14, 10:45 AM, Dicebot wrote:
>>> On Wednesday, 5 March 2014 at 18:39:08 UTC, Andrei Alexandrescu wrote:
>>>> Doesn't enable anything. There'd be a ton more juice in a static
>>>> foreach; it would enable a lot of great idioms. We should pursue that
>>>> instead.
>>>>
>>>> Andrei
>>>
>>> Btw, are there any unexpected design difficulties with static foreach?
>>> Or it is just waiting for someone to do the pull request?
>>
>> 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.
>
> static if needs exactly the same thing, currently the following compiles:
>
> static if(is(int A)){}
> A b; // meh

Good point, thanks!

Andrei

March 05, 2014
On 3/5/14, 1:54 PM, Timon Gehr wrote:
>> Probably worth a DIP. Other than that, we're a go.
>>
>> Andrei
>>
>
> I will create it this weekend if nobody beats me to it.

Walter and I would preapprove implementation of static foreach if and only if a solid DIP comes about.

Andrei

March 05, 2014
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).
- 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).
- 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.
- "static foreach_reverse (immutable i; 0 .. 10)" could be supported.
- "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.

Bye,
bearophile
March 06, 2014
On 2014-03-05 14:09:31 +0000, bearophile said:

> Orvid King wrote:
> 
>> couldn't the first be improved more by allowing something like:
>> 
>> T opOpAssign(string op : in("+", "-", "*", "/", "%", "^^", "&", "|", "^", "<<", ">>", ">>>"), T)(T x)
>> 
>> The `in` there is my attempt to disambiguate between this type of constraint and what I view as the most likely syntax for built-in tuples.
> 
> While a static switch could be a little handy (I have desired it few times, despite a static foreach is much more needed), there's no strong need for that "in", You can use something like (untested):
> 
> T opOpAssign(string op, T)(T x)
> if ("+ - * / % ^^ & | ^ << >> >>>".split.canFind(op))
> 
> Bye,
> bearophile

Actually, there is static foreach if you are iterating over a tuple.  It's not always very obvious under what conditions the compiler evaluates foreach though.

-S