I am thinking to introduce futures to Felix something like this: future x = f (y); println$ y; println$ x;
In this guise, a future is yet another kind of variable evaluation strategy. Like a val, a future can be evaluated when the compiler chooses: either immediately, concurrently, or at the first use. This is also true right now for a val. The main difference to a val is that futures cannot use general lazy evaluation: a future can only be evaluated once, so it's equivalent to lazy evaluation with caching. In the implicit (read-only) form, I propose the following implementation: var x : T; var chan = schannel[T](); spawn_fthread { write$ chan, f y; }; println$ y; x = read chan; println$ x; The main difficulty here is detecting when the read is required. It may be possible to do this statically -- in the above case this seems clear. In more general case we would also need a flag: var x_flag = false; .. if not x_flag do x_flag = true; x = read chan; done This would have to be executed before every use of the variable. In the explicit form, you have to force the evaluation, which just calls the above code. The main problem here is that generators cannot read schannels, only procedures can do that .. so the code has to be written out every time. This also means this implementation of futures could never work in a function. Even if the evaluation did not involve side-effects. [Recall, schannels are read by doing a service call which is done by *returning* controi to the run time scheduler, which implies the machine stack must be empty] However *inlined* functions are always made procedural. Non-tail-recursive functions cannot be completely inlined. However recursive functions can be made procedural. Closures stored in variables can't be inlined either. This is primarily a typing issue: one could easily make a closure of the procedural form of a function. The procedural form of a function is simply the original function with an extra pointer argument, and the returns replaced by a store at the pointer. If the code is reduced to "three address form" by unravelling expressions and introducing temporary variables, we can see all functions can be made procedural. It's actually interesting that because generators which yield only work if their closure is stored in a variable, but that closure can still be a procedure if only the type is converted too, and uses are converted. in fact the ONLY code that cannot be converted is variables of C function type, i.e. callbacks. Even C bindings to functions are trivially converted, although one must not that C procedure bindings still use the machine stack: the contraint becomes that you cannot do service calls within a callback. With static analysis some of the checks on use might be eliminated. The advantage of this method is that the variable appears ordinary. The disadvantage is that the compiler has to replace all uses of the variable, in particular this would be difficult to do right if the variable could be addressed (unless you count that as a use). **** There is another implementation, using objects. interface future[T] { set: 1 -> 0; get: 1 -> T; } object InTheFuture[T] (user_set: &T -> 0) implements future = { var flag = false; var value: T; method proc set () { user_set$ &value; flag = true; } method gen get () { if not flag do set(); done return value; } } looks tempting (it just will NOT work if the user_set tries to read an schannel!) This can actually be fixed by adding a procedure force. That does the read if the flag is not set and sets it. It does nothing if the flag is set already. The get method checks the flag and ABORTS if you haven't forced the read yet. The USER can then write a generator: inline gen getit () { obj.force(); return obj.get(); } which cannot abort. .. this function will be inlined (because it says inline) and it will be lifted out of expressions (because its a generator): you just can't make a closure out of it and expect it to work. [Note .. sorry for the confusion .. but only yielding generators have to be closures! Because only yield implies the generator has to be resumed. So there are really two kinds of generator, those that yield and those that don't] -- john skaller skal...@users.sourceforge.net http://felix-lang.org ------------------------------------------------------------------------------ Monitor your physical, virtual and cloud infrastructure from a single web console. Get in-depth insight into apps, servers, databases, vmware, SAP, cloud infrastructure, etc. Download 30-day Free Trial. Pricing starts from $795 for 25 servers or applications! http://p.sf.net/sfu/zoho_dev2dev_nov _______________________________________________ Felix-language mailing list Felix-language@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/felix-language