Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task system is embarrassingly unexpressive #1128

Closed
marijnh opened this issue Nov 4, 2011 · 1 comment
Closed

Task system is embarrassingly unexpressive #1128

marijnh opened this issue Nov 4, 2011 · 1 comment

Comments

@marijnh
Copy link
Contributor

marijnh commented Nov 4, 2011

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.

Not being able to write generic utility functions around task spawning seems unacceptable. I'm marking this as a blocker because I don't think we can release a language that is supposed to have tasks as one of its interesting features with such a primitive set of task operations. I'm holding off on writing the tutorial section 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<To, From> = fn(comm::port<To>, comm::chan<From>);
fn spawn_connected<uniq To, uniq From>(f: connected_fn<To, From>)
    -> {task: task::task, in: comm::port<From>, out: comm::chan<To>} unsafe {
    fn helper(d: (comm::chan<int>,
                  comm::chan<comm::chan<int>>,
                  connected_fn<int, int>)) {
        let (out, send_in, f) = d;
        let in = comm::port::<int>();
        comm::send(send_in, comm::chan(in));
        f(in, out);
    }
    let in = comm::port::<From>();
    let get_out = comm::port::<comm::chan<To>>();
    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<msg>, out: comm::chan<int>) {
    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);
}
@marijnh
Copy link
Contributor Author

marijnh commented Nov 4, 2011

Oh, this is actually a duplicate of #1038 . Closing, marking that one as a blocker.

@marijnh marijnh closed this as completed Nov 4, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant