digitalmars.D.learn - How to make delegate refer to itself?
- H. S. Teoh (23/23) Nov 23 2013 How do I make a delegate refer to itself? I'm running into a
- lomereiter (6/6) Nov 23 2013 Why so much fuss about delegates? I would simply define an
- H. S. Teoh (12/14) Nov 23 2013 [...]
- Ary Borenszweig (7/11) Nov 23 2013 Split it in declaration and initialization:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (33/54) Nov 23 2013 Timon Gehr's improvement of the Y combinator:
- bearophile (4/6) Nov 23 2013 Nice, I will update the Rosettacode page.
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
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
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
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
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); TTimon 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
Ali Çehreli:Timon Gehr's improvement of the Y combinator: http://forum.dlang.org/post/l55gr6$1ltp$1 digitalmars.comNice, I will update the Rosettacode page. Bye, bearophile
Nov 23 2013