October 28

This works fine –

import std.stdio : writeln;
import std.range : iota, take;
import std.algorithm : filter, map, each;

void main() {
        auto range1 = iota(0, 100)
                        .filter!(x => x % 2)
                        .take(50);
        range1.each!writeln;
}

This also works fine –

void main() {
        auto cls = new Class;
        cls.range1.each!writeln;
}

class Class {
        auto range1 = iota(0, 100)
                        .take(50);
}

But this doesn't –

void main() {
        auto cls = new Class;
        cls.range1.each!writeln;
}

class Class {
        auto range1 = iota(0, 100)
                        .filter!(x => x % 2)
                        .take(50);
}

Adding the .filter! messes things up.

Same with .map!

void main() {
        auto cls = new Class;
        cls.range1.each!writeln;
}

class Class {
        auto range1 = iota(0, 100)
                        .map!(x => x * 2)
                        .take(50);
}

My question is, why?

I mean, am I just dumb or is this some kinda bug?

October 28

On Saturday, 28 October 2023 at 12:38:42 UTC, Subhaditya Nath wrote:

>

This works fine –

I think it's because you're using a class. Try for example:

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

void main() {
    auto cls = new Class;
    cls.range1.each!writeln;
}

class Class {
    auto range1() {
        return iota(0, 100).filter!(x => x % 2).take(25);
    }
}

The lambda function x => x % 2 is created within the class scope, which means it implicitly captures this. The filter function is a template that gets instantiated in a way that requires access to this, which is not available in the static context.

The range1 member is declared like a field within the Class, but it's initialized in place, outside of a constructor or method. This sort of initialization doesn't have access to this because it's not happening within an instance context (like within a method where this is valid).

So, then maybe you understand why it didn't work.