How to make delegate refer to itself?

Ali Çehreli acehreli at yahoo.com
Sat Nov 23 16:15:54 PST 2013


On 11/23/2013 02:57 PM, H. S. Teoh wrote:
> How do I make a delegate refer to itself? I'm running into a
> chicken-and-egg problem where a delegate needs to remove itself from an
> event queue, but I don't know how to make it refer to itself:
>
> 	queue.register((Event e) {
> 		if (e == ...)
> 			queue.remove( /* ??? how to refer to self? */ );
> 	});
>
> I tried this workaround but it still doesn't work:
>
> 	auto dg = (Event e) {
> 		if (e == ...)
> 			queue.remove(dg); // NG: Compiler complains 'dg' isn't defined
> 	};
> 	queue.register(dg);
>
> I thought the auto was the problem, so I changed it to an explicit type,
> but still no cigar:
>
> 	void delegate(Event) dg = (Event e) {
> 		if (e == ...)
> 			queue.remove(dg); // NG: Still complains 'dg' isn't defined
> 	};
> 	queue.register(dg);
>
>
> T
>
Timon Gehr's improvement of the Y combinator:

   http://forum.dlang.org/post/l55gr6$1ltp$1@digitalmars.com

import std.stdio;

alias Event = int;

struct Q
{
     void register(void delegate(Event) dg)
     {
         writeln("register()");
         dg(42);
     }

     void remove(void delegate(Event))
     {
         writeln("removing");
     }
}

auto y(S,T...)(S delegate(T) delegate(S delegate(T)) f){
     struct F{ S delegate(T) delegate(F) f; alias f this; }
     return (x=>x(x))(F(x=>f((T v)=>x(x)(v))));
}

void main()
{
     auto queue = Q();

     auto dg = y((void delegate(Event e) self) =>
         (Event e) {
             if (true)
                 queue.remove(self);
         });
     queue.register(dg);
}

Of course, you don't need main.dg.

Ali



More information about the Digitalmars-d-learn mailing list