I like the IO interface simply for the fact that it would allow me to create language level vfs
Edit: not quite https://news.ycombinator.com/item?id=44549430
181–190 of 293 posts
I like the IO interface simply for the fact that it would allow me to create language level vfs
Edit: not quite https://news.ycombinator.com/item?id=44549430
io.async(saveFile, .{io, data, "saveA.txt"}).await(io);
That is 3 references to `io` in a single call.Considering there is very little use case for mix and matching different Ios, any chance of having some kind of default / context IO to avoid all these ?
So you have to do: io.async(saveFile, .{io, data, "saveA.txt"}).await(io); That is 3 references to `io` in a single call. Considering there is very little use case for mix and matching different Ios, any chance of having some kind of default / context IO to avoid all these ?
saveFile(io, data, "saveA.txt");
EDIT: following up on that, I'm actually not sure that io.async(saveFile, .{io, data, "saveA.txt"}).await(io);
will even be valid code. Futures in this article are declared as var, meaning mutable. This appears to be because Future.await is going to take a pointer as its initial argument. However, because it's a temporary and therefore treated as const, the return value of io.async will not be passable to a .await function expecting a *Future as its initial argument without first being stored in a mutable var.So this would be valid:
var save_future = io.async(saveFile, .{io, data, "saveA.txt"});
save_future.await(io);
But the original presented in the parent comment would be equivalent to the following, and therefore invalid: const save_future = io.async(saveFile, .{io, data, "saveA.txt"});
save_future.await(io); // compile errorThis is a good time to implement "context", a way to pass down the call stack parameters instead of having to add a io argument to every function
A notable example was passing around an implicit ExecutionContext for thread pools, e.g. in Akka :)
Earlier quoted context omitted.
> 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…
> Well, no. In zig that's `const x = foo(io)`. If `foo` needs to do IO, sure. Or, more typically (as I mentioned in a different comment), it's something like `const x = something.foo()`, and `foo` can get its `Io` instance from `something` (in the Zig compiler this would be a `Compilation` or a `Zcu` or a `Sema` or something like that). > Using stackless coroutines and green threads results in a completely different…
Earlier quoted context omitted.
Python, for example, will let you call async functions inside non-async functions, you just have to set up the event loop yourself. This isn't conceptually different than the Io thing here.
except you cant "pass the same event loop in multiple locations". its also not an easy lift. the zig std will provide a few standard implementations which would be trivial to drop in.
I wish Zig had not done async/await. CPS (like you have in Go) is way, way better, and is lower level, making it possible to do you own "async/await" if you really want to.
By CPS do you mean lightweight threads + meeting point channels? (i.e. both the reader and writer get blocked until they meet at the read/write call) Or something else? Why is CPS better and lower level than async/await?
I guess its pure luck if the io implementation can handle both, but who knows?
I feel that I have to point this out once again, because the article goes so far as to state that: > With this last improvement Zig has completely defeated function coloring. I disagree with this. Let's look at the 5 rules referenced in the famous "What color is your function?" article referenced here. > 1. Every function has a color Well, you don't have async/sync/red/blue anymore, but you now have IO and non-IO fun…
Async and coroutines are the graveyard of dreams for systems programming languages, and Andrew by independently rediscovering the IO monad and getting it right? Hope of a generation.
Functions in the real world have colors: you can have predictable rules for moving between colors, or you can wing it and get C++ co_await and tokio and please kill me.
This is The Way.
I feel that I have to point this out once again, because the article goes so far as to state that: > With this last improvement Zig has completely defeated function coloring. I disagree with this. Let's look at the 5 rules referenced in the famous "What color is your function?" article referenced here. > 1. Every function has a color Well, you don't have async/sync/red/blue anymore, but you now have IO and non-IO fun…
Earlier quoted context omitted.
The key difference to typical async function coloring is that `Io` isn't something you need specifically for asynchronicity; it's something which (unless you make a point to reach into very low-level primitives) you will need in order to perform any IO, including reading a file, sleeping, getting the time, etc. It's also just a value which you can keep wherever you want, rather than a special attribute/property of a…
> It's quite rare for a function to unexpectedly gain a dependency on "doing IO" in general. From the code sample it looks like printing to stdio will now require an Io param. So won’t you now have to pass that down to wherever you want to do a quick debug printf?