January 26, 2014
Stanislav Blinov:

> We need generic enumerate() in Phobos :(

It will come soon :-)
https://github.com/D-Programming-Language/phobos/pull/1866
(Take a look at my comment about foreach there)


This also shows we need a good syntax to unpack tuples:

> void main() {
> 	auto myRange = iota(0,10);
> 	auto result = myRange.enumerate.map!(a => a[0] & 1 ? -a[1] : a[1]);
> 	result.writeln;
> }

It could be written like:

myRange.enumerate.map!(t{i, x} => i % 2 ? -x : x);

Bye,
bearophile
January 26, 2014
> I get the following error message :
>
> /usr/include/dmd/phobos/std/range.d(4220): Error: Internal Compiler Error: CTFE literal Tuple(void, void)._expand_field_0
> dmd: ctfeexpr.c:359: Expression* copyLiteral(Expression*): Assertion `0' failed.
> Aborted (core dumped)

Someone already encounter this error here http://is.gd/2rsFQJ ...

January 26, 2014
On Sunday, 26 January 2014 at 13:45:32 UTC, matovitch wrote:

> Anyway, the proposed solutions use twice much memory than a simple for loop...

???

> is the compiler smart enougth to optimize this kind of code ?

There are ongoing discussions on what and how current D compilers optimize nowadays. I don't have a link though.
January 26, 2014
On Sunday, 26 January 2014 at 13:49:34 UTC, bearophile wrote:
> Stanislav Blinov:

>> We need generic enumerate() in Phobos :(
>
> It will come soon :-)
> https://github.com/D-Programming-Language/phobos/pull/1866

Cool!

>
> This also shows we need a good syntax to unpack tuples:

100% agree.

>
> myRange.enumerate.map!(t{i, x} => i % 2 ? -x : x);

Why not just like ((i, x) => i % 2 ? -x : x)? Isn't (a,b,...) how an unpacked tuple should look like?

January 26, 2014
On Sunday, 26 January 2014 at 13:33:58 UTC, matovitch wrote:
> Now DMD compiler segfaulted. Here is my code if you are interested...
>
> struct Bernstein(alias K, int S)
>     if (isBernstein!(K))
> {
>     immutable typeof(K) kernel = K;
>     immutable int shift = S;
> }
>

s/immutable/enum/

?
January 26, 2014
On Sunday, 26 January 2014 at 14:13:28 UTC, Stanislav Blinov wrote:
> On Sunday, 26 January 2014 at 13:45:32 UTC, matovitch wrote:
>
>> Anyway, the proposed solutions use twice much memory than a simple for loop...
>
> ???
>

Well in a for loop, you only need one more index variable whereas here we store the whole index range.
January 26, 2014
On Sunday, 26 January 2014 at 14:22:16 UTC, Stanislav Blinov wrote:
> On Sunday, 26 January 2014 at 13:33:58 UTC, matovitch wrote:
>> Now DMD compiler segfaulted. Here is my code if you are interested...
>>
>> struct Bernstein(alias K, int S)
>>    if (isBernstein!(K))
>> {
>>    immutable typeof(K) kernel = K;
>>    immutable int shift = S;
>> }
>>
>
> s/immutable/enum/
>
> ?

I am a *total* beginner so I am sure my code should look at least strange to experts. How should I write this ? Why ?

ps : It seems the compiler lost the type information when unpacking the tuple ?
This code doesn't compile :

template alternate(alias B)
{
    alias alternate = Bernstein!(
        array(map!(a => a[0])(zip(B.kernel, cycle([-1, 1])))),
        B.shift);
}

January 26, 2014
On Sunday, 26 January 2014 at 14:24:35 UTC, matovitch wrote:

> Well in a for loop, you only need one more index variable whereas here we store the whole index range.

Not the *whole* range, that would be impossible since it's infinite :) In this particular instance, index range is a struct consisting of three variables: initial state (0), current sequencer (n), and current element as cache. D ranges are lazy. Well, most of them.
January 26, 2014
On Sunday, 26 January 2014 at 14:32:48 UTC, Stanislav Blinov wrote:
> On Sunday, 26 January 2014 at 14:24:35 UTC, matovitch wrote:
>
>> Well in a for loop, you only need one more index variable whereas here we store the whole index range.
>
> Not the *whole* range, that would be impossible since it's infinite :) In this particular instance, index range is a struct consisting of three variables: initial state (0), current sequencer (n), and current element as cache. D ranges are lazy. Well, most of them.

This is great ! Let's trust phobos then.
January 26, 2014
On Sunday, 26 January 2014 at 14:29:54 UTC, matovitch wrote:

>> s/immutable/enum/
>>
>> ?
>
> I am a *total* beginner so I am sure my code should look at least strange to experts. How should I write this ? Why ?

I am not sure exactly what are you trying to achieve. My comment meant "ditch immutable, replace with enum" :) Also ditch array() calls. This compiles:

import std.array;
import std.range;
import std.traits;
import std.algorithm;

template isBernstein(alias K) {
    enum bool isBernstein = (K.empty || isNumeric!(typeof(K.front)));
}

struct Bernstein(alias K, int S) if (isBernstein!K)
{
    enum kernel = K;
    enum shift = S;
}

template reverse(alias B)
{
    alias reverse = Bernstein!(retro(B.kernel), -(B.shift + cast(int)B.kernel.length - 1));
}

template alternate(alias B)
{
    alias alternate = Bernstein!(map!(a => a[0] * a[1])(zip(B.kernel, cycle([-1, 1]))), B.shift);
}

void main() {
    alias haar_scale = alternate!(Bernstein!([1.,1.], 0));

    writeln(haar_scale.kernel);
    writeln(haar_scale.shift);
}

I don't know if it works as intended though.

> ps : It seems the compiler lost the type information when unpacking the tuple ?

Which tuple?

> This code doesn't compile :
>
> template alternate(alias B)
> {
>     alias alternate = Bernstein!(
>         array(map!(a => a[0])(zip(B.kernel, cycle([-1, 1])))),
>         B.shift);
> }

It does for me.