> This is similar to IO Monad in Haskell. Adding that to previously pure > computational code is painful, but on the other hand it does emphasis > that computational code != IO code and minimizing mixing between two > typically leads to better design overall. Yes, but you can have the compiler automatically transform normal code into the equivalent of Haskell's "do notation", which is what C# does with async. Basically code like this: async fn foo() -> uint { let a: int = compute_a(); let b: int = compute_b(); let c: char = await read_char(); let r: uint = compute_r(a, b, c); return r; } becomes after the compiler performs CPS transform: // assume that we have trait Continuation<T> {fn continue<T>(~self, v: T);} // assume that cps_read_char is provided by the runtime and tells a main loop to read a char and then schedule a new task running the passed continuation struct foo_Continuation(~Continuation<uint>, int, int); fn cps_foo(continuation: ~Continuation<uint>) { let a: int = compute_a(); let b: int = compute_b(); return cps_read_char(~foo_Continuation(continuation, a, b)); } impl Continuation<char> for foo_Continuation { fn continue(~self, c: char) { let (continuation, a, b) = *self; let r = compute_r(a, b, c); continuation.continue(r); } } and then a future-based version can also be generated by the compiler based on the CPS transform results: // assume that Continuation<T> is implemented on TaskFuture<T> and causes the TaskFuture to be completed with the value fn future_foo() -> ~TaskFuture<int> { let f = ~TaskFuture::new(); cps_foo(f); return f; } Note that if foo() had taken a borrowed pointer with lifetime 'a, then the CPS version becomes unsafe, and TaskFuture would also need an 'a parameter. Also, one can use a borrowed pointer instead of an owned pointer for continuations and futures, but then they need to be waited on before its lifetime region ends.
_______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev