www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Mixin - to get to the content-type `MapResult!(__lambda1,

reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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 29 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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 29 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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
next sibling parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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 30 2015
parent reply "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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 30 2015
next sibling parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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 30 2015
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
parent "Dennis Ritchie" <dennis.ritchie mail.ru> writes:
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; }
May 31 2015