A warning about a gotcha that just bit me: Service calls are not allowed in functions. That includes generators.
This means you cannot do schannel I/O, you cannot do sleeps, and you cannot spawn fthreads in a generator. If you do this, the code may compile, but it won't work. This is because these operations yield to the driver code to do the service calls. Procedures yield by simply returning from their C++ resume() method, so when the operation is done the driver resumes them where they left off. Functions cannot yield, because they return a value. There are two workarounds. The ugly one is to convert the generator to a procedure: add a parameter which is the address of the return value and store the return value at that address, instead of returning it. A call like var x = f y; will then have to be changed to: var x: T; f (y, &x); The second work around. This is easier: inline gen f (...) .... Just make the generator inline. This leads to code bloat. It also slows the compiler down a LOT. There should be a way to force the compiler to convert a function into a procedure. The compiler can do this, in fact it usually does, so *sometimes* you will get away with service calls in functions. In fact the "futures" library code relies on this. Note that a generator can be passed as an argument, that is, a closure formed. When this happens the procedural form can't be used because it would have the wrong type. In theory this can be fixed, by eliminating functions altogether: converting functional to procedural code universally is entirely possible (closures included). We just make A -> B a shorthand for A * &B -> 0. There are two arguments against this though: first, we assume our C++ compiler is dumb: it is better at doing optimisations on expressions than sequences of statements. This is because expressions have a linear typing property: returns are rvalues which are immediately consumed. So the flow analysis is simpler than a function with variables where the lifetime has to be calculated with an expensive flow analysis. The second reason is that we sometimes want to generate callbacks for C code which have to be C functions returning a value. This COULD still be done. Remember C functions have a distinct type anyhow: A --> B // as opposed to A -> B Finally I will note: there's actually no good reason that "spawn_fthread" require a service call if I changed the semantics back to the old model, where the spawned thread is delayed instead of invoked immediately. -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Slashdot TV. Video for Nerds. Stuff that matters. http://tv.slashdot.org/ _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language