www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Cool Trick: Currying for stack-on-heap style delegates

reply Russell Lewis <webmaster villagersonline.com> writes:
As everybody knows, delegate literals currently use a pointer to the 
stack frame as their "this" pointer, meaning that they cannot be 
returned from a function, or used after the frame exits.  Some of us 
have argued for a "copy the stack frame" syntax.  I'm stumbled upon a 
pretty cool trick to accomplish the same thing (although it can get 
tedious when you draw too many variables into the delegate).  The trick 
is to declare a function literal instead of a delegate literal, and then 
use a Curry() template to pass stack variables into the function:

void delegate() myFunc()
{
   int a,b,c;
   ....
   return Curry(a,b,c, function void(int a,int b,int c) {
                         // put your code here
                       });
}



Obviously, this gets a little ugly as you get more and more variables, 
particularly as the types get complex.  I've been pondering better 
syntax possibilities, using the keyword "curry."  A couple of ideas that 
I had were:


DECLARATION FORM (short, but only useful for bringing in variables 
declared in the outer scope):

return delegate void() {
     curry a; // declare that 'a' from the outer scope should be passed
              // as a curried argument to this delegate
   }

EXPRESSION FORM (more flexible):

return delegate void() {
     auto a = curry a; // the expression "curry a" resolves to the
                       // reading of a hidden, curried argument which
                       // gets its value from the outer scope
   }

To clarify, the EXPRESSION FORM example above would be equivalent to:

return Curry(a, void function(int _temp) {
                   auto a = _temp;
                 });
Sep 04 2007
parent Daniel Keep <daniel.keep.lists gmail.com> writes:
Russell Lewis wrote:
 As everybody knows, delegate literals currently use a pointer to the
 stack frame as their "this" pointer, meaning that they cannot be
 returned from a function, or used after the frame exits.  Some of us
 have argued for a "copy the stack frame" syntax.  I'm stumbled upon a
 pretty cool trick to accomplish the same thing (although it can get
 tedious when you draw too many variables into the delegate).  The trick
 is to declare a function literal instead of a delegate literal, and then
 use a Curry() template to pass stack variables into the function:
 
 [... snip ...]

There's also this trick: http://while-nan.blogspot.com/2007/08/fakin-closures.html -- Daniel
Sep 04 2007