I see several proposals for the future of Rust tasks, and I think one of the best approaches is being overlooked, and that is something similar to async in C# (http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx).
In C#, the "async" keyword can be applied to functions and it causes the compiler to transform a function that returns T into a function that returns a Task<T> (which is C#'s name for a future of type T) representing the potentially asynchronous computation. Blocking is representing by using the "await" keyword on a future (typically returned by a call to another "async" function), and it causes the compiler to perform a Continuation-Passing Style transformation, and attach the continuation to the future, returning another future representing the composed computation. I/O functions are designed to return futures, so in this system blocking causes all calling "async" functions to return, building up a chain of continuations on the heap, which is equivalent to the machine stack in a current-Rust task, but which is as small as needed, and is only used for call chains that block. In Rust, this transformation is much more delicate, because the resulting return value futures must have a lifetime that is the smallest among all the arguments to the function, if those arguments are needed by the continuation, and the argument types must be "shareable" between parallel forks (e.g. std::rc::Rc is not shareable because RC manipulation is non-atomic). However, it is possible to restrict the system to use non-delimited continuations instead of the delimited continuations and futures, which would avoid this problem, since futures cannot be used explicitly anymore (at the cost of making flexible parallelism impossible). In this latter case, it would be equivalent to the current task system, except for requiring blocking functions to be marked "async"; the "await" keyword would not be required, since it would effectively become compulsory if there are no first-class futures returned for async functions. Advantages: - Functions and interfaces that can perform I/O or can block are clearly marked by a keyword - Can have billions of blocked tasks (with hundreds of gigabytes of RAM) since the memory used by each blocked task is truly minimized because it's on the heap Disadvantages: - Requires an heap allocation for every function call to an async function (to hold the continuation data) - Non-"async" functions cannot call "async" functions, so interfaces must be explicitly marked as async or not - Requires to implement the transform in the compiler Microsoft switched to this paradigm in the latest version of C# and in the Windows RT API, and it might be an appropriate choice for Rust too.
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev