Skip to content

Async function yield statements #5611

@adrusi

Description

@adrusi

Here's my implementation of generators in Zig 0.6.0. As far as I can tell there's no elegant way in current Zig to eliminate the intermediate copy of all values yielded by the generator. There's also a less important issue where the ritual for yielding a value is a bit ugly:

item.* = VALUE;
suspend;

I'm going to propose something that should fix both problems, and which I think is the most minimal change to make generators a proper feature. The idea is to add a pointer parameter to the calling convention for (some?) async functions, one which gets written to by yield VALUE statements. Some pseudocode:

fn foo() void yield u8 {
    var n: u8 = 0;
    while (true) {
        yield n;
        n += 1;
    }
}

fn bar() {
    var item: u8;
    var frame = async(&item) foo();
    warn("{}\n", .{ item });
    resume frame;
    warn("{}\n", .{ item });
    var item2: u8;
    @setYieldLocation(frame, &item2);
    resume frame;
    warn("{}\n", .{ item2 });
}

In this illustrative syntax, the parameter to async sets the pointer that yield writes to. The yield statement writes to that pointer and suspends. @setYieldLocation allows the caller to change the pointer after the initial creation of the frame. Once #2765 is resolved, this should allow a userland wrapper to implement a next() function without requiring an intermediate copy.

This adds quite a bit of surface area to the language. A minimal alternative that requires no language changes besides #2765 is for the userland implementation of next() to communicate the yield pointer to the generator code explicitly. This would require changing the yield ritual from

item.* = VALUE;
suspend;

to

item.*.* = VALUE;
suspend;

I consider this to be a bit too cumbersome, and it breaks with the ideal of making the right way to code the easiest way as well, since dropping the double-pointer still works, as long as you tolerate the intermediate copy.

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions