www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to make delegate refer to itself?

reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
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

-- 
Heuristics are bug-ridden by definition. If they didn't have bugs, they'd be
algorithms.
Nov 23 2013
next sibling parent reply "lomereiter" <lomereiter gmail.com> writes:
Why so much fuss about delegates? I would simply define an 
interface.

// factory function for simple cases
queue.register(eventHandler((Event e) { ... }));

// here, 'this' is available
class SomeComplicatedHandler : IEventHandler { ... }
Nov 23 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sun, Nov 24, 2013 at 12:15:23AM +0100, lomereiter wrote:
 Why so much fuss about delegates? I would simply define an
 interface.
[...] I know I can do that (and in fact it's what I had before). But classes and interfaces are rather heavy (more indirection, allocates vtables, etc.), and require the declaration of tiny classes everywhere, which is a pain when I have many tiny code snippets I wish to register and unregister in various places. Using delegates is much cleaner (thanks to lambda syntax) and lighter weight, especially when I need to close over local variables. T -- May you live all the days of your life. -- Jonathan Swift
Nov 23 2013
prev sibling next sibling parent Ary Borenszweig <ary esperanto.org.ar> writes:
On 11/23/13 7:57 PM, H. S. Teoh wrote:
 void delegate(Event) dg = (Event e) {
 		if (e == ...)
 			queue.remove(dg); // NG: Still complains 'dg' isn't defined
 	};
Split it in declaration and initialization: void delegate(Event) dg; dg = (Event e) { if (e == ...) queue.remove(dg); };
Nov 23 2013
prev sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
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
Nov 23 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Ali Çehreli:

 Timon Gehr's improvement of the Y combinator:

   http://forum.dlang.org/post/l55gr6$1ltp$1 digitalmars.com
Nice, I will update the Rosettacode page. Bye, bearophile
Nov 23 2013