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