On Thursday, 1 August 2019 at 21:26:10 UTC, Matt wrote:
Anyone have any other thoughts?

I tried to simplify your example a little bit:

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

auto myFilter(R1, R2)(R1 a, R2 b)
{
    return a.filter!(c => c==b.front);
}

struct A
{
    int[] starts;

    auto intervalRange() @property
    {
        return starts;
    }
}

auto uniqIntervalsA(A primary, A* previous) @property
{
    return choose(previous is null,
                  primary.intervalRange,
primary.intervalRange.filter!(a => a==previous.intervalRange.front));
}

auto uniqIntervalsB(A primary, A* previous) @property
{
    return choose(previous is null,
                  primary.intervalRange,
primary.intervalRange.myFilter(previous.intervalRange));
}

unittest
{
    auto a1 = A([1]);

    writeln(uniqIntervalsA(a1,&a1));
    writeln(uniqIntervalsA(a1,null));
    writeln(uniqIntervalsB(a1,&a1));
    writeln(uniqIntervalsB(a1,null));
}

The strange thing is, that even if you replace "return a.filter!(c => c==b.front);" by "return a.filter!(c => true);" the problem remains (but now you can use lazy). As I'm not an expert myself, I'm not sure how to analyze this. But I think, both parameters to "choose" are evaluated (that is they are not lazy), but "myFilter" uses it's parameter immediately to give "b" a value, while "filter" just hands in an anonymous function without using it ever.

Hope, this helps to get further down the way to a solution...

Reply via email to