The future of lambda delegates

BCS BCS at pathlink.com
Wed Aug 16 09:57:28 PDT 2006


Mikola Lysenko wrote:
[...]
> All the syntactic sugar is nice, but 
> it also lays a few traps for the unwary.
[...]
> 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:
> 
> Button createButton(char[] click_msg)
> {
>     Button b = new Button();
>     b.mouseClickCallback = { MsgBox(click_msg); };
>     return b;
> }
> 
[...]
> As a final example, suppose we 
> want to perform a lengthy calculation in a separate thread, and only wait 
> for the value once it is needed.  In this case, one could try to do the 
> following:
> 
> int[] delegate() sort_threaded(int[] array)
> {
>     int[] result = array.dup;
> 
>     //Create and run a worker thread to perform an expensive operation, (in 
> this case a sort)
>     Thread tsort = new Thread(
>      {
>         result.sort;
>         return 0;
>      });
>     tsort.start();
> 
>     //The returned lambda delegate waits for the thread's calculation to 
> finish, then returns the result.
>     return { tsort.wait; return result; };
> }
> 
[...]
> It is very sad that none of these examples work, 
> since there are so many nice solutions just like them.
> 
> One possible solution is to allocate the frame for each function containing 
> nested-functions on the heap.  
[...]
> Such a translation is possible for any of these examples, albeit quite 
> tedious.  
[...]
> 
> Any thoughts or comments?
> 
> -Mikola Lysenko 
> 
> 

Interesting ideas, however using a struct rather than a class would be 
faster.

Maybe what is needed is some way to define the context pointer of a 
delegate literal.


int[] delegate() sort_threaded(int[] array)
{
     auto foo = new struct   // this might need new syntax
     {
         int[] result;
         Thread tsort;
     };

     with(foo)
     {
         result = array.dup;
                             // delegate with alt context
         tsort = new Thread(foo.{
             result.sort;
             return 0;
         });
         tsort.start();
     }
                             // delegate with alt context
     return foo.{
         // array[0];        // not in scope
         tsort.wait;
         return result;
     };
}


This would also work on another of the examples:

Button createButton(char[] click_msg)
{
     Button b = new Button();
     b.mouseClickCallback = click_msg.{ MsgBox(this); };
     return b;
}


for the first example some sort of joining of the anon struct 
deceleration and with statement might make this vary elegant


int[] delegate() sort_threaded(int[] array)
{
         // (using mixin for lack of a better syntax)
         // inject these into the namespace,
         //but put them on the heep
     mixin foo = new struct
     {
         int[] result;
         Thread tsort;
     };

     result = array.dup;
     tsort = new Thread(foo.{
         result.sort;
         return 0;
     });

     tsort.start();

     return foo.{
         tsort.wait;
         return result;
     };
}




More information about the Digitalmars-d mailing list