Value closures (no GC allocation)

Vittorio Romeo via Digitalmars-d digitalmars-d at puremagic.com
Sat May 20 17:33:30 PDT 2017


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?


More information about the Digitalmars-d mailing list