I'm trying to figure out how to use coroutines in D. First, I think I've run into some kind of bug. I've followed this C++ example: http://www.subatomicglue.com/secret/coro/readme.html, and came up with this:
import std.stdio; import core.thread; void fiberFunc(size_t arg) { int i = 0; foreach (x; 0 .. 1000) { writefln("fiber waiting (id = %d)", arg); Fiber.yield(); } foreach (x; 0 .. 1000) { writefln("fiber running (iter = %d id = %d)", ++i, arg); Fiber.yield(); } while (1) { writefln("fiber waiting (id = %d)", arg); Fiber.yield(); } } void main() { Fiber[200] fibers; foreach (ref fiber; fibers) { fiber = new Fiber(&fiberFunc); } while (true) { foreach (fiber; fibers) { fiber.call(); } } } Only after I've translated the C++ example to D I've realized that fiberFunc actually takes an argument. But from what I can tell core.thread.Fiber never calls this function with any arguments. I have a hunch that "arg" ends up having an uninitialized garbage value, so it looks like this is a bug? Ok, that put aside what I really want to emulate is this Python example of a coroutine (perhaps bearophile is familiar with this): def coroutine(func): def start(*args,**kwargs): cr = func(*args,**kwargs) cr.next() return cr return start @coroutine def unwrap_protocol(header='\x61', footer='\x62', dle='\xAB', after_dle_func=lambda x: x, target=None): """ Simplified framing (protocol unwrapping) co-routine. """ # Outer loop looking for a frame header # while True: byte = (yield) frame = '' if byte == header: # Capture the full frame # while True: byte = (yield) if byte == footer: target.send(frame) break elif byte == dle: byte = (yield) frame += after_dle_func(byte) else: frame += byte @coroutine def frame_receiver(): """ A simple co-routine "sink" for receiving full frames. """ while True: frame = (yield) print 'Got frame:', frame.encode('hex') bytes = ''.join(chr(b) for b in [0x70, 0x24, 0x61, 0x99, 0xAF, 0xD1, 0x62, 0x56, 0x62, 0x61, 0xAB, 0xAB, 0x14, 0x62, 0x7 ]) unwrapper = unwrap_protocol(target=frame_receiver()) for byte in bytes: unwrapper.send(byte) This was taken from Eli's blog: http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/ I'm not seeing any way of yielding a value back from a Fiber or even sending it, so I don't see how I can use fibers to implement coroutines which send or return values. But I'm new to the concept so maybe I'm missing something obvious?