On 05/20/2016 12:56 PM, Yuxuan Shui wrote:
> On Friday, 20 May 2016 at 06:40:42 UTC, Jacob Carlborg wrote:
>> On 2016-05-20 04:14, Yuxuan Shui wrote:
>>
>>> Hmm... This could work. But I'm not satisfied with this solution. What
>>> if I have multiple yield sites in the fiber, and each have different
>>> return types?
>>>
>>> Maybe I should use a Variant?
>>
>> I think you can view "yield" as a form of "return". If you cannot
>> return different types from a function (without it being a template)
>> it would be weird if you could yield different types.
>
> But this is yield as in coroutine, not yield as in generators. Those
> yields doesn't return value to the caller of the fiber.
>
> Let's have an example:
>
> void func() {
>     string a = wait_for_user_input();
>     int b = wait_for_user_to_click_a_button();
> }
>
> Those two wait()s could use yield internally to transfer execution back
> to the caller and wait for input. But it's difficult with current dlang
> fiber because there's no (elegant) way to pass data (preferably with
> different types) while transferring executing to/from fibers.

Agreed. Fibers are not a language construct.

One has to do what std.concurrency.Generator does internally. In this case, we need another layer of function calls. (I could have used Generator below and I could avoid creating a fiber for each call by moving the fibers to module-scope.)

import core.thread;

void input_fiber(ref string input) {
    while (true) {
        input = "hello";
        Fiber.yield();
    }
}

string wait_for_user_input() {
    string input;
    auto f = new Fiber(() => input_fiber(input));
    f.call();
    return input;
}

void click_fiber(ref int button) {
    while (true) {
        button = 42;
        Fiber.yield();
    }
}

int wait_for_user_to_click_a_button() {
    int button;
    auto f = new Fiber(() => click_fiber(button));
    f.call();
    return button;
}

void func() {
    foreach (i; 0 .. 10) {
        string a = wait_for_user_input();
        assert(a == "hello");

        int b = wait_for_user_to_click_a_button();
        assert(b == 42);
    }
}

void main() {
    func();
}

Ali

Reply via email to