Thread overview
Mixin - to get to the content-type `MapResult!(__lambda1, int[]).MapResult`
May 30, 2015
Dennis Ritchie
May 30, 2015
Ali Çehreli
May 30, 2015
Dennis Ritchie
May 30, 2015
Dennis Ritchie
May 30, 2015
Ali Çehreli
May 31, 2015
Dennis Ritchie
May 31, 2015
Dennis Ritchie
May 31, 2015
Ali Çehreli
May 31, 2015
Dennis Ritchie
May 30, 2015
Hi,
This code prints the arrays:
[5]
[6]
[7]

import std.stdio, std.algorithm;

static int idx;

void walk(R)(R range) {
    while (!range.empty) {
        range.front;
        range.popFront;
        ++idx;
    }
}

void main() {
    [5, 6, 7].map!(a => [a].writeln).walk;
}

How should I apply mixins to `range.front` to the program to print the arrays:
[0, 5]
[1, 6]
[2, 7]

Ie I want to get something like this:

void walk(R)(R range) {
    while (!range.empty) {
        // mixin(`[idx ~ "mixin("range.front")"[1 .. $]);`);
        range.popFront;
        ++idx;
    }
}

Can I do this?

-----
Thank you for the function `walk` Mark Isaacson of presentation DConf 2015:
http://dconf.org/2015/talks/isaacson.pdf
May 30, 2015
On 05/29/2015 06:07 PM, Dennis Ritchie wrote:

> Hi,
> This code prints the arrays:
> [5]
> [6]
> [7]
>
> import std.stdio, std.algorithm;
>
> static int idx;

Do you want to share that for the first element of every two-element array or do you want to start from 0 for every range?

> void walk(R)(R range) {
>      while (!range.empty) {
>          range.front;
>          range.popFront;
>          ++idx;
>      }
> }

As a reminder, there is also the recent 'each', which is eager as well.

> void main() {
>      [5, 6, 7].map!(a => [a].writeln).walk;
> }
>
> How should I apply mixins to `range.front` to the program to print the
> arrays:
> [0, 5]
> [1, 6]
> [2, 7]

Unless mixin required for another reason, there are other ways of achieving the same.

> Ie I want to get something like this:
>
> void walk(R)(R range) {
>      while (!range.empty) {
>          // mixin(`[idx ~ "mixin("range.front")"[1 .. $]);`);
>          range.popFront;
>          ++idx;
>      }
> }
>
> Can I do this?
>
> -----
> Thank you for the function `walk` Mark Isaacson of presentation DConf 2015:
> http://dconf.org/2015/talks/isaacson.pdf

The following program produces the desired output twice. The first one starts from 0 for the index, the second one shares the index as in your code.

import std.stdio, std.algorithm, std.range;

void main() {
    zip(sequence!"n", [5, 6, 7])
        .map!(a => [a.expand])
        .each!writeln;

    static int idx;

    [5, 6, 7]
        .map!(a => [idx++, a])
        .each!writeln;
}

Ali

May 30, 2015
On Saturday, 30 May 2015 at 06:50:09 UTC, Ali Çehreli wrote:
> On 05/29/2015 06:07 PM, Dennis Ritchie wrote:
>
> > Hi,
> > This code prints the arrays:
> > [5]
> > [6]
> > [7]
> >
> > import std.stdio, std.algorithm;
> >
> > static int idx;
>
> Do you want to share that for the first element of every two-element array or do you want to start from 0 for every range?

I want to share...

> > void walk(R)(R range) {
> >      while (!range.empty) {
> >          range.front;
> >          range.popFront;
> >          ++idx;
> >      }
> > }
>
> As a reminder, there is also the recent 'each', which is eager as well.

But I want to do this is to `map` :)

> > void main() {
> >      [5, 6, 7].map!(a => [a].writeln).walk;
> > }
> >
> > How should I apply mixins to `range.front` to the program to
> print the
> > arrays:
> > [0, 5]
> > [1, 6]
> > [2, 7]
>
> Unless mixin required for another reason, there are other ways of achieving the same.

I just want to present the results of the intermediate performance (which I plan to reach through the mixin) `range.front` as a string, to then modify it with the help of mixin to get directly to the array.

> > Ie I want to get something like this:
> >
> > void walk(R)(R range) {
> >      while (!range.empty) {
> >          // mixin(`[idx ~ "mixin("range.front")"[1 .. $]);`);
> >          range.popFront;
> >          ++idx;
> >      }
> > }
> >
> > Can I do this?
> >
> > -----
> > Thank you for the function `walk` Mark Isaacson of
> presentation DConf 2015:
> > http://dconf.org/2015/talks/isaacson.pdf
>
> The following program produces the desired output twice. The first one starts from 0 for the index, the second one shares the index as in your code.
>
> import std.stdio, std.algorithm, std.range;
>
> void main() {
>     zip(sequence!"n", [5, 6, 7])
>         .map!(a => [a.expand])
>         .each!writeln;
>
>     static int idx;
>
>     [5, 6, 7]
>         .map!(a => [idx++, a])
>         .each!writeln;
> }

Thank you for your examples, but I want to do something else.

Ie I want to access the intermediate generation `range.front` with two mixins or by other means. `range` is of type `MapResult!(__lambda1, int[])([5, 6, 7], null)` — I want to get the generation of this intermediate, i.e. something like `range.front` --> `[5].writeln` and present `[5].writeln` as a string, to modify the line like so `[5].writeln` --> `[5].writeln`[1 .. $] --> `[idx ~ `[5].writeln`[1 .. $]` --> `[idx, 5].writeln` with the help of mixins. :)

I want to access the intermediate generation `range.front`. Is it possible? :)
May 30, 2015
On Saturday, 30 May 2015 at 19:19:21 UTC, Dennis Ritchie wrote:
> I want to access the intermediate generation `range.front`. Is it possible? :)

In other words, I want to expand the array to the application to him of 'writeln'!
May 30, 2015
On 05/30/2015 12:19 PM, Dennis Ritchie wrote:

First, unfortunately, I don't understand you completely. Sorry about that... :)

Second, you can do almost anything with string mixins: Write a function that returns the code as string and just mix it in. :) Debug with pragma(msg):

string makeCode(string name)
{
    return `int ` ~ name ~ ` = 42;`;
}

unittest
{
    assert(makeCode("foo") == "int foo = 42;");
}

> I want to access the intermediate generation `range.front`. Is it
> possible? :)

Regarding that, the intermediate range.front is already available right before the .walk part. You can do anything at that point. There was some proposals about a 'tap' algorithm that could be used for debugging purposes. Here is a quick implementation:

import std.stdio, std.algorithm;

static int idx;

void walk(R)(R range) {
    while (!range.empty) {
        range.front;
        range.popFront;
    }
}

struct Tap(alias func, R)
{
    R range;

    alias range this;

    @property auto front()
    {
        func(range.front);
        return range.front;
    }
}

auto tap(alias func, R)(R range)
{
    return Tap!(func, R)(range);
}

void main() {
    [5, 6, 7]
        .map!(a => [idx++, a])
        .tap!((a) { writeln(a[1..$]); })  /* <-- This can use the
                                           * lambda syntax as well but
                                           * note that the return
                                           * value of the lambda is
                                           * ignored. So I think this
                                           * syntax is more
                                           * helpful. */
        .walk;
}

Ali

May 31, 2015
On Saturday, 30 May 2015 at 23:58:44 UTC, Ali Çehreli wrote:
> On 05/30/2015 12:19 PM, Dennis Ritchie wrote:
>
> First, unfortunately, I don't understand you completely. Sorry about that... :)

Nothing to worry about! Now you will understand me till the end... :)

> Regarding that, the intermediate range.front is already available right before the .walk part. You can do anything at that point. There was some proposals about a 'tap' algorithm that could be used for debugging purposes. Here is a quick implementation:

Yes, it is an intermediate stage of code that will help me to explain what I want to get.

> import std.stdio, std.algorithm;
>
> static int idx;
>
> void walk(R)(R range) {
>     while (!range.empty) {
>         range.front;
>         range.popFront;
>     }
> }
>
> struct Tap(alias func, R)
> {
>     R range;
>
>     alias range this;
>
>     @property auto front()
>     {
          func(range.front); // It's a necessary part of the code! :)
>         return range.front;
>     }
> }
>
> auto tap(alias func, R)(R range)
> {
>     return Tap!(func, R)(range);
> }
>
> void main() {
>     [5, 6, 7]
>         .map!(a => [idx++, a])
>         .tap!((a) { writeln(a[1..$]); })  /* <-- This can use the
>                                            * lambda syntax as well but
>                                            * note that the return
>                                            * value of the lambda is
>                                            * ignored. So I think this
>                                            * syntax is more
>                                            * helpful. */
>         .walk;
> }
>
> Ali

I don't know, maybe it's something out of science fiction, but here's what I want to do :)

struct Tap(alias func, R)
{
    R range;

    alias range this;

    @property auto front()
    {
        immutable string myStr = `func(mixin("range.front"));`;
	immutable string newStr = `mixin(myStr);`;
	writeln(newStr); // I want them to be printed here `writeln([5]);`
        mixin(newStr[0 .. $ - 4] ~ `[idx,` ~ newStr[$ - 4 .. $]); // I want them to be printed here `[0, 5];`
        return range.front;
    }
}

Is it possible to do using mixins or through any other means? Ie I want to catch the moment when `func` is replaced by the invocation of `writeln` :)
May 31, 2015
On Sunday, 31 May 2015 at 06:04:40 UTC, Dennis Ritchie wrote:
> mixin(newStr[0 .. $ - 4] ~ `[idx,` ~ newStr[$ - 4 .. $]);

mixin(newStr[0 .. $ - 4] ~ `idx,` ~ newStr[$ - 4 .. $]);
May 31, 2015
On 05/30/2015 11:04 PM, Dennis Ritchie wrote:

> struct Tap(alias func, R)
> {
>      R range;
>
>      alias range this;
>
>      @property auto front()
>      {
>          immutable string myStr = `func(mixin("range.front"));`;
>      immutable string newStr = `mixin(myStr);`;
>      writeln(newStr); // I want them to be printed here `writeln([5]);`
>          mixin(newStr[0 .. $ - 4] ~ `[idx,` ~ newStr[$ - 4 .. $]); // I
> want them to be printed here `[0, 5];`
>          return range.front;
>      }
> }
>
> Is it possible to do using mixins or through any other means? Ie I want
> to catch the moment when `func` is replaced by the invocation of
> `writeln` :)

So, you want to skip that extra func() call and have the code be "inlined". That's one of the things what any decent optimizing compiler does anyway.

I hear great things especially about ldc and that gdc is just good enough. Of course, one needs to check the assembly output to be sure that there is no extra function calls.

Ali

May 31, 2015
On Sunday, 31 May 2015 at 07:28:02 UTC, Ali Çehreli wrote:
> So, you want to skip that extra func() call and have the code be "inlined". That's one of the things what any decent optimizing compiler does anyway.

Yes, I think that there is an extra function call, because DMD is based on Zortech C++ backend, so I figured ... :)

> I hear great things especially about ldc and that gdc is just good enough. Of course, one needs to check the assembly output to be sure that there is no extra function calls.
>
> Ali

And yet in DMD I'm not sure :)

import std.stdio, std.algorithm;

static int idx;

void walk(R)(R range) {
	while (!range.empty) {
		range.front;
		range.popFront;
	}
}

struct Tap(alias func, R)
{
	R range;
	
	alias range this;
	
	@property auto front()
	{
		func(range.front);
		return range.front;
	}
}

auto tap(alias func, R)(R range)
{
	writeln(__FUNCTION__); // ???
	return Tap!(func, R)(range);
}

void main() {
	[5, 6, 7]
		.map!(a => [idx++, a])
		.tap!((a) { writeln(a[1..$]); })
		.walk;
}