The future of lambda delegates
Regan Heath
regan at netwin.co.nz
Wed Aug 16 19:07:34 PDT 2006
On Thu, 17 Aug 2006 01:15:15 +0100, Bruno Medeiros
<brunodomedeirosATgmail at SPAM.com> wrote:
> nobody wrote:
>> Mikola Lysenko wrote:
>>
>>> Recent D releases (notably 0.161) have updated the syntax and improved
>>> the overall usability of lambda delegates. All the syntactic sugar is
>>> nice, but it also lays a few traps for the unwary. Here is a simple
>>> example:
>>>
>>> // The Fibonacci numbers are an integer sequence such that
>>> // F(n) = F(n - 1) + F(n - 2)
>>> // And F(0) = 0, F(1) = 1
>>> int delegate() fibs()
>>> {
>>> int a = 0; // Initialize the last two terms of the
>>> Fibonacci int b = 1;
>>>
>>> return
>>> {
>>> int c = a + b; // Calculate the next term in the sequence
>>> a = b; // Shift the previous terms back
>>> b = c;
>>> return c; // Return the result
>>> };
>>> }
>>>
>>> This function returns a function which will sequentially evaluate all
>>> of the Fibonacci numbers. Notice that the inner delegate modifies the
>>> variables a and b in fibs() scope. Because of this, it is not
>>> guaranteed to work after fibs returns. This is most irritating, and
>>> it greatly restricts the use of this technique. Another potential use
>>> for lambda delegates is to create one-line adapter methods. Consider
>>> the following attempt to create a button which will display an
>>> arbitrary message when clicked:
>> It took me awhile to get what you were doing but it is elegant -- or
>> would be if it worked. I am sure I am missing something however so I
>> hope you might explain why using static storage is not sufficient:
>> int delegate() fibs()
>> {
>> return
>> {
>> static int a = 0;
>> static int b = 1;
>> int c = a + b;
>> a = b;
>> b = c ;
>> return c;
>> };
>> }
>>
>
> For starters, a delegate can access the outer function arguments, but
> those arguments cannot be made static.
>
> And then there will only be one "instance" of the returned delegate
> (think of the delegate as an object). Any call to it will update only
> one single sequence:
>
> auto dg1 = fibs();
> auto dg2 = fibs();
> dg1(); // 1
> dg1(); // 2
> dg2(); // 3
> dg2(); // 5
>
> However, with proper "heaped" frames, there are many delegate (outer
> frame) "instances":
>
> auto dg1 = fibs();
> auto dg2 = fibs();
> dg1(); // 1
> dg1(); // 2
> dg1(); // 3
> dg2(); // 1
> dg2(); // 2
> dg2(); // 3
So, the other option is:
import std.stdio;
// The Fibonacci numbers are an integer sequence such that
// F(n) = F(n - 1) + F(n - 2)
// And F(0) = 0, F(1) = 1
int delegate(inout int,inout int) fibs()
{
return (inout int a, inout int b)
{
int c = a + b; // Calculate the next term in the sequence
a = b; // Shift the previous terms back
b = c;
return c; // Return the result
};
}
void main()
{
int a = 0,b = 1;
writefln(fibs()(a,b));
writefln(fibs()(a,b));
writefln(fibs()(a,b));
writefln(fibs()(a,b));
writefln(fibs()(a,b));
writefln(fibs()(a,b));
writefln(fibs()(a,b));
}
Right? Passing the storage location to the calls.
Regan
More information about the Digitalmars-d
mailing list