4 ms·
You’re allowed to not like it, but that doesn’t change that your argument that this is a form of coloring is objectively false. I’m not sure what Rust has to do
by n42 1y ago
You’re allowed to not like it, but that doesn’t change that your argument that this is a form of coloring is objectively false. I’m not sure what Rust has to do with it.
- rowanG077 1y agoSure it is a function coloring. Just in a different form. `async` in other languages is something like an implicit parameter. In zig they made this implicit parameter explicit. Is that more better/more ergonomic? I don't know yet. The sugar is different, but the end result the same. Unless you can show me concrete example of things that the approach zig has taken can do that is not possible in say, rust. Than I don't buy that it's not just another form of function coloring.
- throwawaymaths 1y ago> Unless you can show me concrete example add io to a struct and let the struct keep track of its own io.
- gfaster 1y agoUnless I'm misunderstanding, that's effectively implementing Future for the struct
- masklinn 1y agoIt’s more like adding a runtime handle to the struct. Modulo that I’m not sure any langage with a sync/async split has an “async” runtime built entirely out of sync operations. So a library can’t take a runtime for a caller and get whatever implementation the caller decided to use.
- dwattttt 1y ago> I’m not sure any langage with a sync/async split has an “async” runtime built entirely out of sync operations. You get into hairy problems of definition, but you can definitely create an "async" runtime out of "sync" operations: implement an async runtime with calls to C. C doesn't have a concept of "async", and more or less all async runtime end up like this. I've implemented Future (Rust) on a struct for a Windows operation based only on C calls into the OS. The struct maintains everything needed to know the state of the IO, and while I coupled the impl to the runtime for efficiency (I've written it too), it's not strictly necessary from memory.
- masklinn 1y ago> You get into hairy problems of definition, but you can definitely create an "async" runtime out of "sync" operations: implement an async runtime with calls to C. C doesn't have a concept of "async", and more or less all async runtime end up like this. While C doesn't have async OS generally provide APIs which are non-blocking, and that is what async runtimes are implemented on top of. By sync operations I mean implementing an "async" runtime entirely atop blocking operations, without bouncing them through any sort of worker threads or anything.
- dwattttt 1y agoI've been pondering this, it feels like a brain teaser. Is it possible to create an "async" runtime out of only blocking operations? It feels like it turns purely on what "blocking operations" are (does setting a lock bit and returning count as non-blocking?)
- rowanG077 1y agoYou can also carry around a runtime and dispatch async function in non-async functions.
- dminik 1y agoIt's funny, but I do actually like it. It's just that it walks like a duck, swims like a duck and quacks like a duck. I don't have a problem with IO conceptually (but I do have a problem with Zig ergonomics, allocator included). I do have a problem with claiming you defeated function coloring. Like, look. You didn't even get rid of await ... > try a_future.await(io);
- mlugg 1y agoI mean... you use `await` if you've used `async`. It's your choice whether or not you do; and if you don't want to, your callers and callees can still freely `async` and `await` if they want to. I don't understand the point you're trying to make here. To be clear, where many languages require you to write `const x = await foo()` every time you want to call an async function, in Zig that's just `const x = foo()`. This is a key part of the colorless design; you can't be required to acknowledge that a function is async in order to use it. You'll only use `await` if you first use `async` to explicitly say "I want to run this asynchronously with other code here if possible". If you need the result immediately, that's just a function call. Either way, your caller can make its own choice to call you or other functions as `async`, or not to; as can your callees.
- dminik 1y ago> in Zig that's just ... Well, no. In zig that's `const x = foo(io)`. The moment you take or even know about an io, your function is automatically "generic" over the IO interface. Using stackless coroutines and green threads results in a completely different codegen. I just noticed this part of the article: > Stackless Coroutines > > This implementation won’t be available immediately like the previous ones because it depends on reintroducing a special function calling convention and rewriting function bodies into state machines that don’t require an explicit stack to run. > > This execution model is compatible with WASM and other platforms where stack swapping is not available or desireable. I wonder what will happen if you try to await a future created with a green thread IO using a stackless coroutine IO.
- mlugg 1y ago