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