On Thursday, 7 April 2016 at 08:27:23 UTC, Edwin van Leeuwen wrote:
On Thursday, 7 April 2016 at 08:17:38 UTC, Puming wrote:
On Thursday, 7 April 2016 at 08:07:12 UTC, Edwin van Leeuwen wrote:

OK. Even if it consumes the first two elements, then why does it have to consume them AGAIN when actually used? If the function mkarray has side effects, it could lead to problems.

After some testing it seems to get each element twice, calls front on the MapResult twice, on each element. The first two mkarray are both for first element, the second two for the second. You can solve this by caching the front call with:

xs.map!(x=>mkarray(x)).cache.joiner;

There is another problem with cache, that is if I want another level of this map&joiner(which is my code scenario, where I'm reading a bunch of files, with each one I need to read multiple locations with seek and return a bunch of lines with each seek), adding cache will result compiler error:

simplified demo:

auto read(int a) {
   writeln("read called!", a);
   return [0, a]; // second level
}

auto mkarray(int a) {
  writeln("mkarray called!", a);
return [-a, a].map!(x=>read(x)).cache.joiner; // to avoid calling read twice
}

void main() {
  auto xs = [1,2 ,3, 4];
auto r = xs.map!(x=>mkarray(x)).cache.joiner; // to avoid calling mkarray twice

  writeln(r);
}

When compiled, I get the error:

Error: open path skips field __caches_field_0
source/app.d(19, 36): Error: template instance std.algorithm.iteration.cache!(MapResult!(__lambda1, int[])) error instantiating

Reply via email to