graydon/rust — Issue #1128: Task system is embarrassingly unexpressive
Author: marijnh
Created: 2011-11-04 14:07:37+00:00
State: open
Labels: blocker

The primitives provided in `task` and `comm` are *very* primitive. Too primitive to write a tutorial chapter about without sounding completely lame. So I tried to write a helper function which helps create a channel back from a child task to its parent. None of the existing tests or examples seem to do this. And, apparently, with good reason.

Below is what I have. It doesn't work. Writing new task-creation utilities will typically require type parameters. We currently can not spawn functions with type parameters, so the 'landing pad' helper that such a utility would spawn, can not be generic.

I half got around this with a clunky `reinterpret_cast`, but the resulting program doesn't work when the `To` type has a different size than an `int`, because the port being created in `helper` doesn't know its type.

I'm holding off on writing about tasks until we figure out a solution here. (Or maybe it already exists and I just didn't see it.)

```
use std;
import std::{task, comm};

type connected_fn = fn(comm::port, comm::chan);
fn spawn_connected(f: connected_fn)
-> {task: task::task, in: comm::port, out: comm::chan} unsafe {
fn helper(d: (comm::chan,
comm::chan>,
connected_fn)) {
let (out, send_in, f) = d;
let in = comm::port::();
comm::send(send_in, comm::chan(in));
f(in, out);
}
let in = comm::port::();
let get_out = comm::port::>();
let task = task::spawn((comm::chan(in), comm::chan(get_out), f),
std::unsafe::reinterpret_cast(helper));
ret {task: task, in: in, out: comm::recv(get_out)};
}

tag msg { msg(int); quit; }

fn worker(in: comm::port, out: comm::chan) {
while true {
alt comm::recv(in) {
msg(i) { comm::send(out, i * 10); }
quit. { break; }
}
}
}

fn main() {
let {task, in, out} = spawn_connected(worker);
comm::send(out, msg(20));
log_err comm::recv(in);
comm::send(out, quit);
}
```