Proof of concept/proposal: reference counted closures/delegates

Jakob Ovrum via Digitalmars-d digitalmars-d at puremagic.com
Tue Nov 10 17:27:44 PST 2015


I wrote a proof of concept that explores how we could support 
fully featured reference counted closures:

     https://gist.github.com/JakobOvrum/69e64d82bcfed4c114a5

The proof_of_concept code path is just to show that the `scope` 
trick works.

The with_new_trait code path proposes a new trait 
__traits(upvalues, func) which takes an alias to a function and 
returns an alias sequence describing the function's upvalues:

     (T1, ptrdiff_t offset1, T2, ptrdiff_t offset2, ...)

Where each pair is the type of the upvalue and the upvalue's 
offset in bytes from the context pointer, which can be negative. 
This trait allows the library code to properly postblit and 
destroy upvalues, as well as being a reliable way to get the 
required size of the closure.

The benefit of this approach is that it should work as a drop-in 
replacement for delegates, whether they're nested/anonymous 
functions or member functions. One difference from delegates is 
that conversion between functions of different attributes has to 
be explicit (with the constructor and opAssign).

It shares the downside with delegates that upvalues aren't packed 
together, so while the proposed trait *can* be used to make 
C++-style value-type closures, they would carry junk in between 
the upvalues.

As for the example implementation, I have more ideas to improve 
it, particularly regarding attribute propagation and code bloat 
elimination, but I'd rather do that if the new trait is 
implemented.

Any thoughts?



More information about the Digitalmars-d mailing list