the implementation of futures relies on a hack/implementation detail which I have disturbed reorganising the compiler.
Here's the problem: I have implemented futures by spawning an fthread (fibre) which sends the result down an schannel. To get the result you read the schannel. More precisely you call a function which checks if the result has been fetched already, if not it reads the schannel and caches the result. This is a "perfect" implementation of futures, however it isn't legal in Felix because reading and schannel (and spawning an fthread) aren't allowed in functions (or generators). They're only allowed in procedures (and ones not nested in functions). However Felix has some optimisations, including the ability to convert a function fun f(x:D):C = ... into a procedure equivalent to: proc f' (p:&C, x:D) { *p = f x; } where the code of f is inserted rather than calling it. That means if f is called in a procedure f' is called instead and as long as that procedure's ancestors are procedural, side effects including spawning fthreads and reading channels are allowed. Closures of functions demand the original function though, the type has to be right. Ok, so in theory it is possible to spawn an fthread in a function. There are two ways to do this: the first is to put it on the master scheduler. But another way is to start a scheduler inside the function. One can the run an fthread inside the function, and provided it has no external side effects it would be all quite legal. What is also important to note is that when a fthread does synchronous I/O if it is blocked, it becomes owned by the schannel. So at that point it isn't associated with any particular scheduler (indeed an schannel is, itself, a kind of scheduler). This means, even though not completed, a nested scheduler can terminate, allowing the caller (including a function is that started the scheduler) to continue. Whichever scheduler receives the balancing I/O request will resume the reader thread, and schedule the writer. So fthread can MOVE from one scheduler to another via cross scheduler matching of I/O requests. Unfortunately, it's hard to know when to start a new scheduler. In principle, one could do it in EVERY function. At present, procedure calls from a function ARE started with a mini-scheduler, but it is a trivial one that can't handle I/O or spawns. It basically just resumes the current continuation repeatedly until it dies like this: while (p) p=p->resume(); Actually there is a try/catch as well since Felix allows throwing continuations. This code is small and fast. Starting a complete scheduler will use more time and memory. So it it is done it should either be done manually or the compiler has to detect when a full scheduler is required. Anyhow the bottom line is .. futures are broken. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Comprehensive Server Monitoring with Site24x7. Monitor 10 servers for $9/Month. Get alerted through email, SMS, voice calls or mobile push notifications. Take corrective actions from your mobile device. http://pubads.g.doubleclick.net/gampad/clk?id=154624111&iu=/4140/ostg.clktrk _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language