is std.algorithm.joiner lazy?

Puming via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Apr 7 02:55:56 PDT 2016


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


More information about the Digitalmars-d-learn mailing list