Hello everyone, I recently started learning D (I come from a Modern C++ background) and I was curious about closures that require GC allocation. I wrote this simple example:

    auto bar(T)(T x) @nogc
    {
        return x(10);
    }

    auto foo(int x) @nogc
    {
        return bar((int y) => x + y + 10);
    }

    int main() @nogc
    {
        return foo(10);
    }



It doesn't compile with the following error:

Error: function example.foo is @nogc yet allocates closures with the GC
           example.foo.__lambda2 closes over variable x at [...]



Live example on godbolt: https://godbolt.org/g/tECDh4



I was wondering whether or not D could provide some syntax that allowed the user to create a "value closure", similar to how C++ lambdas work. How would you feel about something like:


    auto bar(T)(T x) @nogc
    {
        return x(10);
    }

    auto foo(int x) @nogc
    {
        return bar([x](int y) => x + y + 10);
    }

    int main() @nogc
    {
        return foo(10);
    }



The syntax:

    [x](int y) => x + y + 10

would mean "create a 'value closure' that captures `x` by value inside it". It would be equivalent to the following program:

    struct AnonymousClosure
    {
        int captured_x;

        this(int x) @nogc
        {
            captured_x = x;
        }

        auto opCall(int y) @nogc
        {
            return captured_x + y + 10;
        }
    }

    auto foo(int x) @nogc
    {
        return bar(AnonymousClosure(x));
    }



Which is very similar to how C++ lambdas work. This would allow closures to be used in @nogc contexts with minimal syntactical overhead over classical closures.

Live example on godbolt: https://godbolt.org/g/ML2dlP

What are your thoughts? Has something similar been proposed before?

Reply via email to