August 21, 2013
On 8/21/13 4:52 AM, John Colvin wrote:
> On Wednesday, 21 August 2013 at 02:46:06 UTC, Dylan Knutson wrote:
>> Hello,
>>
>> I'd like to open up discussion regarding allowing foreach loops which
>> iterate over a tuple of types to exist outside of function bodies.
>
> I would *LOVE* to have this.
>
> however, once we go down that route, it would be very tempting to allow
> a whole lot of other compile-time imperative style programming. Which
> would be awesome.

Not necessarily. We could allow "static foreach" as a functional construct that binds in turn a symbol to each element in a collection.

A static foreach in conjunction with string mixins would be great for simplifying code generation, e.g. "for each method in that class generate a method here".


Andrei


August 21, 2013
Dicebot:

> This bugzilla entry is on slightly related but different topic.
>
> "declaration foreach" != "static foreach"

I think a well implemented "static foreach" is able to do anything a "declaration foreach" could do, and more. (If you don't think so, please show what's missing).

Bye,
bearophile
August 21, 2013
On Wednesday, 21 August 2013 at 18:52:56 UTC, bearophile wrote:
> Dicebot:
>
>> This bugzilla entry is on slightly related but different topic.
>>
>> "declaration foreach" != "static foreach"
>
> I think a well implemented "static foreach" is able to do anything a "declaration foreach" could do, and more. (If you don't think so, please show what's missing).
>
> Bye,
> bearophile

They are orthogonal and not exclusive.

"declaration foreach" can appear whenever declaration can appear and insert new declarations, contrary to statements of normal foreach. "static foreach" is simply an improvement over existing "tuple foreach concept" which allows it to work with a wider variety of input. Former is about context of  foreach itself, latter - about behavior of the loop.
August 21, 2013
Dicebot:

> They are orthogonal and not exclusive.
>
> "declaration foreach" can appear whenever declaration can appear and insert new declarations, contrary to statements of normal foreach. "static foreach" is simply an improvement over existing "tuple foreach concept" which allows it to work with a wider variety of input. Former is about context of  foreach itself, latter - about behavior of the loop.

They are the same thing, in Issue 4085 the step n.6 covers that.

Bye,
bearophile
August 21, 2013
On Wednesday, 21 August 2013 at 18:52:56 UTC, bearophile wrote:
> Dicebot:
>
>> This bugzilla entry is on slightly related but different topic.
>>
>> "declaration foreach" != "static foreach"
>
> I think a well implemented "static foreach" is able to do anything a "declaration foreach" could do, and more. (If you don't think so, please show what's missing).
>
> Bye,
> bearophile

I do like the idea of it being called 'static foreach' instead of 'foreach', to keep in step with how the rest of the language handles other compile time constructs (static assert). Plus, as you said in your bugreport, visual disambiguation between that and a runtime foreach is nice feedback for the programmer to pick up instantly.
August 21, 2013
On Wednesday, 21 August 2013 at 10:02:33 UTC, Tommi wrote:
>
> Why not just do this:
>
> import std.typetuple;
>
> T foo(T)(ref T thing)
> {
>     thing++; return thing * 2;
> }
>
> unittest
> {
>     foreach(Type; TypeTuple!(int, long, uint))
>     {
>         {
>             Type tmp = 5;
>             assert(foo(tmp) == 12);
>         }
>
>         {
>             Type tmp = 0;
>             foo(tmp);
>             assert(tmp == 1);
>         }
>     }
> }

Well, that's one way to go about doing it. But, this seems sub-optimal because a defining trait of unittests is that they're as small and focused on a single behavior for an object/function/whatever as possible. Grouping all testing into a single unittest breaks this convention.

Not to mention, we've got 'static if', and 'static assert', which can exist outside of function bodies and operate on compile time determinable values. It seems like a strange exception for foreach (which can already operate on compile time values) to be excluded from this group.
August 22, 2013
On 08/21/2013 07:45 PM, Andrei Alexandrescu wrote:
> On 8/21/13 4:52 AM, John Colvin wrote:
>> On Wednesday, 21 August 2013 at 02:46:06 UTC, Dylan Knutson wrote:
>>> Hello,
>>>
>>> I'd like to open up discussion regarding allowing foreach loops which
>>> iterate over a tuple of types to exist outside of function bodies.
>>
>> I would *LOVE* to have this.
>>
>> however, once we go down that route, it would be very tempting to allow
>> a whole lot of other compile-time imperative style programming. Which
>> would be awesome.
>
> Not necessarily. We could allow "static foreach" as a functional
> construct that binds in turn a symbol to each element in a collection.
> ...

Yup.

> A static foreach in conjunction with string mixins would be great for
> simplifying code generation, e.g. "for each method in that class
> generate a method here".
>

AFAIK one only reason why it hasn't made it in yet were implementation issues related to DMD internals? The design was discussed in 2007's dconf IIRC.

>
> Andrei
>
>

We really need to define a consistent semantics for compile time symbol manipulation though.

Eg:

class C{
    int a;
    static foreach(x;__traits(allMembers,C)){
        mixin("int "~__traits(identifier,x)~"b;");
    }
}

What is this supposed to do? "class C{ int a,ab; }"? Non-terminating compilation? Error?

My best guess is that the above code should be illegal, but there is a lot of similar code already out in the wild that works by chance. Eg. I guess some of Manu's bindings only work by luck. Thrift for D also contains one or two questionable constructs, as David has shown me recently. (It is possible that this is related to the recent breakage, DMD does not necessarily behave consistently w.r.t. to this kind of code across versions.)

Most of the times this has been brought up it was simply ignored, but it is a glaring hole in D's design.
August 22, 2013
On 08/22/2013 02:56 PM, Timon Gehr wrote:
>
> AFAIK one reason why it hasn't made it in yet were implementation
> issues related to DMD internals? The design was discussed in 2007's
> dconf IIRC.

fixed.
August 22, 2013
On 08/21/2013 10:53 PM, Dylan Knutson wrote:
>>
>
> I do like the idea of it being called 'static foreach' instead of
> 'foreach', to keep in step with how the rest of the language handles
> other compile time constructs (static assert). Plus, as you said in your
> bugreport, visual disambiguation between that and a runtime foreach is
> nice feedback for the programmer to pick up instantly.

It's important to keep them separate regardless. static foreach is close to useless if it introduces a new scope for its body.

I.e.:

int main(){
    foreach(_;Seq!int){
        int x;
    }
    return x; // error
}

int main(){
    static foreach(_;Seq!int){
        int x;
    }
    return x; // ok
}
August 22, 2013
On 08/21/2013 09:17 PM, Dicebot wrote:
>
> They are orthogonal and not exclusive.
>
> "declaration foreach" can appear whenever declaration can appear and
> insert new declarations, contrary to statements of normal foreach.
> "static foreach" is simply an improvement over existing "tuple foreach
> concept" which allows it to work with a wider variety of input. Former
> is about context of  foreach itself, latter - about behavior of the loop.

I disagree. I think the relationship between foreach and static foreach should essentially mirror that of if and static if.
1 2
Next ›   Last »