Search
```I mentioned this in .announce, where the 1 response was positive...I thought I'd post it here to see if I could draw more discussion (positive or negative, I'm interested in both sides).

The idea is a "curry expression", which is an expression inside a delegate literal whose value is computed at the time when the delegate is created, and the computed value is then passed as a curried parameter to the delegate.  (In D, currying is where you declare a hidden struct on the heap which carries within it some arguments to be passed to a delegate.  When you call the delegate, the curry mechanism passes *both* the curried arguments and your call-time arguments (if any) to the underlying function.  http://en.wikipedia.org/wiki/Currying)

Here is a basic example:
int delegate() foo(int i)
{
return delegate int() { return curry i; }
}
The above is syntax sugar for the much less readable:
int delegate() foo(int i)
{
return Curry(i,
delegate int(int temp) { return temp; });
}
where Curry(...) is a template which curries one or more arguments into a delegate.

The point here is that this mechanism allows you to "copy" the stack frame (or, at least, as much of the stack frame as you need) into a delegate which will still be runnable after the stack returns.

LOTS MORE EXAMPLES:

Interesting things happen if you curry pointers:
void delegate(int) SetThisLater(int *ptr)
{
return delegate void(int i) { *(curry ptr) = i; };
}

I don't see any reason why you couldn't have more complex expressions in a curry expression:
real delegate(real) StrangeFunc(real r1)
{
// this calls SomeComplexFunc(r1) once (at delegate creation time)
// and then curries the result
return delegate real(real r2)
{ return r2+ curry SomeComplexFunc(r1); };
}
real delegate(real) StrangeFunc2(real r1)
{
// this calls SomeComplexFunc each time that the delegate is called
return delegate real(real r2)
{ return r2+ SomeComplexFunc(curry r1); };
}

Sometimes, you want to keep a "running tally" of the results from many different calls to the same delegate.  Typically, you would do this simply by updating a stack variable.  But that doesn't work if you need to keep the delegate alive after the stack returns.  You can do it this way:
int delegate(int) RunningSum()
{
return delegate(int i)
{
// "new int" is run at delegate creation time.  So each
// time that you call this delegate, sum is set to the
// *same* pointer to the *same* int on the heap.
int *sum = curry new int;
(*sum) += i;
return *sum;
};
}

Of course, you can still access your stack variables, if you want.  You can even access variables in some expressions, even if they were curried into the delegate in other places:
void Repeat(int count, void delegate() callback)
{
for(int i=0; i<count; i++)
callback();
}
void MyFunc()
{
int i = 1;
Repeat(10, delegate void()
{
// the "curry i" below always uses the curried value
// the "i" below reads from the stack frame
writefln("%d %d", curry i, i);

// this modifies the variable in the stack frame
i++;
};
}
The code above would print:
1 1
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10

Thoughts?
```
```Russell Lewis wrote:
>   int delegate() foo(int i)
>   {
>     return delegate int() { return curry i; }
>   }