Oh FINALLY. This is (in my opinion) one of the ugliest parts of game/graphics programming in zig. There’s an example in the release notes but I think a before & after makes it clearer:
Oh that’s so much better. It’ll even help with my window manager some just w.r.t. scaling certain buffers.
technetium
The integer and float casting improvements are all very neat:
const f: f64 = @sqrt(@floatFromInt(N))
const a: u8 = @round(f)
Things like this were always a pain in the neck for me, since my main Zig project is a little roguelike. I'm sure it's not what folks think of when you say "game development" (I'd call it "lite game development" instead), but it helps all the same! Can't wait to see what other ergonomic improvements make it out.
I'm also happy to see the Future type and general async being added to the language again, even if it's only in the standard library. In the past I (ab)used async to produce generators, which I used heavily for things like animations and such. Those animations became 1.5-2x code when I had to convert them to a state machine, so I look forward to seeing if the new async system is capable of the same thing.
environment variables are available only in the application's main function.
I recall that glibc has a nonstandard extension where, if a certain symbol is defined, glibc calls the symbol with a copy of the environment map and thus allows dynamic and shared libraries to access the environment without being passed a copy. Would this be considered as a Linux-only alternative?
veqq
when I had to convert them to a state machine
What was the migration like? Were you able to only transform the implementation and maintain the overall API or?
technetium
Honestly don't recall (though yes, the API was changed, though only somewhat since the steps are the same: call a function to get the initial animation object, call next() or continue on it). I know one of the animations was a PITA, but that's probably just because I was smooth brained and couldn't keep track of where the animation was doing what and how to cleanly turn it into a state machine. Before, After. (Yes, all terrible code, of which I'm deeply ashamed )))
badtuple
Woo! Congratulations on the release! Thanks to the team for all their hard work.
I'm super excited to kick the tires on the std.Io interface. Even ignoring the sexier justifications like addressing function coloring and swappable concurrency models, injecting IO just feels like the right way to do things. Isolating effects isn't just for the functional peeps ;) . I can't wait for the ergonomic debugging and testing capabilities this enables. Not having to awkwardly stub out any IO dependency just to test it is going to be a game changer for larger projects that need to ensure correctness.
"Juicy main" is a huge quality of life improvement. Not having to set up an allocator and do all this preamble when writing a quick program is great. I expect it will help many more people get into the language. I imagine the juggling to set up the debug allocator right upfront was just enough friction for people to bounce off before they actually got into things.
Was surprised to see the "Forbid Trivial Local Address Returned from Functions" section which is awesome...but more importantly it hides a link to planned work to also error on returned local references! I don't think I've run into these issues in years, but I definitely did starting out. I imagine that'll go a long way for anyone hesitant about Zig's safety story.
kbd
injecting IO just feels like the right way to do things
Agree, when I was a junior I kept bugging seniors about how to test code that does I/O. Their consistent response was basically "wrap the world in your own interface and pass it in". Then it is mockable, testable, etc. That always seemed so wrong to me. Turns out all languages before Zig just did it wrong and having your stdlib designed to pass I/O in is indeed the right way.
Edit: of course even without the language stdlib supporting you like Zig, software design concepts like "functional core / imperative shell" would have been helpful from the seniors.
kneeawn
The 'Juicy Main' bit is interesting. I don't think I've seen this approach taken to this level. I know that in C/C++ you can optionally have argc and argv (apparently envp is implementation defined) and in Austral, you can optionally have a RootCapability. Are there other examples of this (besides languages doing the C/C++ thing)?
kbd
Ooh, juicy main looks great. That'll cut down on a lot of the boilerplate when starting a new program. I was literally thinking earlier "I'd like to start a new zig program, ugh gotta start by cutting and pasting some boilerplate from my other programs".
paulocuambe
for me this is one of the most exciting new features of this version. have been playing around with it on master for a few weeks and have been delighted
Arya
Depends which part you mean: if you're thinking about changing the parameters of main that "something" then introspects and calls it with the right parameters. Raku does CLI argument parsing this way.
Aks
I should use Zig just for the cute mascots.
LAC-Tech
Zig is undergoing a lot of churn. I am not really seeing a rhyme or reason for most of it.
I used to use it, but I got sick of re-writing my programs - so at this point I think I'll wait until Zig 1.0, which is realistically some time next decade.
mrjbq7
I've been following along since Zig 0.11 or so, and it does sometimes feel like churn but most of the improvements are for the better, and you gain new features along the way. I ported a large codebase to Zig 0.16 and it's quite approachable.
I'm really liking where things are going.
You can always leave old programs using old versions of Zig. Things like the Zig Version Manager make it easy to use multiple versions. I do suggest using more recent stuff to get all the latest goodies they've been cooking up.
bitshift
I wonder if a Zig equivalent of tools like gofix or 2to3 would be possible or useful. Some of the churn seems amenable to automatic fixups, such as the new @ builtins.
vaguelytagged
The cancellation part looks extremely interesting this is something that rust definitely struggles with. I don’t completely understand the section here. Do they drive the future to completion and disregard the result if you cancel? How do they prevent things like futurelock or just general issues caused by a canceled future effecting other parts of the code in unexpected ways
rvrb
I am probably not qualified to answer this, and responding in hope that if I am understanding it incorrectly someone will correct me so I can learn something.
most (all?) IO calls can return error.Canceled. when a task is cancelled, the task chugs along until the next call to such a method. the task can choose to do whatever it wants with that information: cleanup, ignore it, stop immediately. once the error is handed to the task, however, the canceled flag on that task is reset. if it wants to, it can recancel itself to propagate cancellation onward.
there's also "cancel protection", which is I think critical in preventing futurelock by giving the task the ability to clean up properly.
so cancellations are requested, can be respected or ignored, and the future locking is prevented because they get to cleanup while protecting from more cancellation.
I had a conversation with Andrew at some point about how syscalls are interrupted, but it was slightly over my head.
andrewrk
These questions are difficult for me to answer because despite implementing async/await in Zig 4 different times in 4 different ways over the last 10 years, every time I've tried to understand the way async works in Rust I have failed to develop a coherent mental model for it.
To the best of my understanding, there's no such thing as "futurelock" in Zig, and none of the other footguns with Rust async, because it works fundamentally differently. When you async something in Zig, it starts happening right away. It doesn't get "polled" later by an "executor" or whathaveyou.
From the notes:
When cancelation is requested, the request may or may not be acknowledged. Acknowledged cancelation requests cause I/O operations to return error.Canceled. Even Io.Threaded supports cancelation by sending a signal to a thread, causing blocking syscalls to return EINTR, and responding to that error code by checking for a cancelation request before retrying the syscall.
In general, cancelation is equivalent to awaiting, aside from the request to cancel. This means you can still receive the return value from the task - which may in fact have completed successfully despite the request. In this case, the side effects, such as resource allocation, should be accounted for. Here is an example of opening a file and then immediately canceling the task. Note that we must account for the possibility that the file succeeds in being opened.
Oh FINALLY. This is (in my opinion) one of the ugliest parts of game/graphics programming in zig. There’s an example in the release notes but I think a before & after makes it clearer:
Oh that’s so much better. It’ll even help with my window manager some just w.r.t. scaling certain buffers.
technetium
The integer and float casting improvements are all very neat:
const f: f64 = @sqrt(@floatFromInt(N))
const a: u8 = @round(f)
Things like this were always a pain in the neck for me, since my main Zig project is a little roguelike. I'm sure it's not what folks think of when you say "game development" (I'd call it "lite game development" instead), but it helps all the same! Can't wait to see what other ergonomic improvements make it out.
I'm also happy to see the Future type and general async being added to the language again, even if it's only in the standard library. In the past I (ab)used async to produce generators, which I used heavily for things like animations and such. Those animations became 1.5-2x code when I had to convert them to a state machine, so I look forward to seeing if the new async system is capable of the same thing.
environment variables are available only in the application's main function.
I recall that glibc has a nonstandard extension where, if a certain symbol is defined, glibc calls the symbol with a copy of the environment map and thus allows dynamic and shared libraries to access the environment without being passed a copy. Would this be considered as a Linux-only alternative?
veqq
when I had to convert them to a state machine
What was the migration like? Were you able to only transform the implementation and maintain the overall API or?
technetium
Honestly don't recall (though yes, the API was changed, though only somewhat since the steps are the same: call a function to get the initial animation object, call next() or continue on it). I know one of the animations was a PITA, but that's probably just because I was smooth brained and couldn't keep track of where the animation was doing what and how to cleanly turn it into a state machine. Before, After. (Yes, all terrible code, of which I'm deeply ashamed )))
badtuple
Woo! Congratulations on the release! Thanks to the team for all their hard work.
I'm super excited to kick the tires on the std.Io interface. Even ignoring the sexier justifications like addressing function coloring and swappable concurrency models, injecting IO just feels like the right way to do things. Isolating effects isn't just for the functional peeps ;) . I can't wait for the ergonomic debugging and testing capabilities this enables. Not having to awkwardly stub out any IO dependency just to test it is going to be a game changer for larger projects that need to ensure correctness.
"Juicy main" is a huge quality of life improvement. Not having to set up an allocator and do all this preamble when writing a quick program is great. I expect it will help many more people get into the language. I imagine the juggling to set up the debug allocator right upfront was just enough friction for people to bounce off before they actually got into things.
Was surprised to see the "Forbid Trivial Local Address Returned from Functions" section which is awesome...but more importantly it hides a link to planned work to also error on returned local references! I don't think I've run into these issues in years, but I definitely did starting out. I imagine that'll go a long way for anyone hesitant about Zig's safety story.
kbd
injecting IO just feels like the right way to do things
Agree, when I was a junior I kept bugging seniors about how to test code that does I/O. Their consistent response was basically "wrap the world in your own interface and pass it in". Then it is mockable, testable, etc. That always seemed so wrong to me. Turns out all languages before Zig just did it wrong and having your stdlib designed to pass I/O in is indeed the right way.
Edit: of course even without the language stdlib supporting you like Zig, software design concepts like "functional core / imperative shell" would have been helpful from the seniors.
kneeawn
The 'Juicy Main' bit is interesting. I don't think I've seen this approach taken to this level. I know that in C/C++ you can optionally have argc and argv (apparently envp is implementation defined) and in Austral, you can optionally have a RootCapability. Are there other examples of this (besides languages doing the C/C++ thing)?
kbd
Ooh, juicy main looks great. That'll cut down on a lot of the boilerplate when starting a new program. I was literally thinking earlier "I'd like to start a new zig program, ugh gotta start by cutting and pasting some boilerplate from my other programs".
paulocuambe
for me this is one of the most exciting new features of this version. have been playing around with it on master for a few weeks and have been delighted
Arya
Depends which part you mean: if you're thinking about changing the parameters of main that "something" then introspects and calls it with the right parameters. Raku does CLI argument parsing this way.
Aks
I should use Zig just for the cute mascots.
LAC-Tech
Zig is undergoing a lot of churn. I am not really seeing a rhyme or reason for most of it.
I used to use it, but I got sick of re-writing my programs - so at this point I think I'll wait until Zig 1.0, which is realistically some time next decade.
mrjbq7
I've been following along since Zig 0.11 or so, and it does sometimes feel like churn but most of the improvements are for the better, and you gain new features along the way. I ported a large codebase to Zig 0.16 and it's quite approachable.
I'm really liking where things are going.
You can always leave old programs using old versions of Zig. Things like the Zig Version Manager make it easy to use multiple versions. I do suggest using more recent stuff to get all the latest goodies they've been cooking up.
bitshift
I wonder if a Zig equivalent of tools like gofix or 2to3 would be possible or useful. Some of the churn seems amenable to automatic fixups, such as the new @ builtins.
vaguelytagged
The cancellation part looks extremely interesting this is something that rust definitely struggles with. I don’t completely understand the section here. Do they drive the future to completion and disregard the result if you cancel? How do they prevent things like futurelock or just general issues caused by a canceled future effecting other parts of the code in unexpected ways
rvrb
I am probably not qualified to answer this, and responding in hope that if I am understanding it incorrectly someone will correct me so I can learn something.
most (all?) IO calls can return error.Canceled. when a task is cancelled, the task chugs along until the next call to such a method. the task can choose to do whatever it wants with that information: cleanup, ignore it, stop immediately. once the error is handed to the task, however, the canceled flag on that task is reset. if it wants to, it can recancel itself to propagate cancellation onward.
there's also "cancel protection", which is I think critical in preventing futurelock by giving the task the ability to clean up properly.
so cancellations are requested, can be respected or ignored, and the future locking is prevented because they get to cleanup while protecting from more cancellation.
I had a conversation with Andrew at some point about how syscalls are interrupted, but it was slightly over my head.
andrewrk
These questions are difficult for me to answer because despite implementing async/await in Zig 4 different times in 4 different ways over the last 10 years, every time I've tried to understand the way async works in Rust I have failed to develop a coherent mental model for it.
To the best of my understanding, there's no such thing as "futurelock" in Zig, and none of the other footguns with Rust async, because it works fundamentally differently. When you async something in Zig, it starts happening right away. It doesn't get "polled" later by an "executor" or whathaveyou.
From the notes:
When cancelation is requested, the request may or may not be acknowledged. Acknowledged cancelation requests cause I/O operations to return error.Canceled. Even Io.Threaded supports cancelation by sending a signal to a thread, causing blocking syscalls to return EINTR, and responding to that error code by checking for a cancelation request before retrying the syscall.
In general, cancelation is equivalent to awaiting, aside from the request to cancel. This means you can still receive the return value from the task - which may in fact have completed successfully despite the request. In this case, the side effects, such as resource allocation, should be accounted for. Here is an example of opening a file and then immediately canceling the task. Note that we must account for the possibility that the file succeeds in being opened.
Oh FINALLY. This is (in my opinion) one of the ugliest parts of game/graphics programming in zig. There’s an example in the release notes but I think a before & after makes it clearer:
Before:
After:
Oh that’s so much better. It’ll even help with my window manager some just w.r.t. scaling certain buffers.
The integer and float casting improvements are all very neat:
const f: f64 = @sqrt(@floatFromInt(N))const a: u8 = @round(f)Things like this were always a pain in the neck for me, since my main Zig project is a little roguelike. I'm sure it's not what folks think of when you say "game development" (I'd call it "lite game development" instead), but it helps all the same! Can't wait to see what other ergonomic improvements make it out.
I'm also happy to see the
Futuretype and general async being added to the language again, even if it's only in the standard library. In the past I (ab)used async to produce generators, which I used heavily for things like animations and such. Those animations became 1.5-2x code when I had to convert them to a state machine, so I look forward to seeing if the new async system is capable of the same thing.I recall that
glibchas a nonstandard extension where, if a certain symbol is defined,glibccalls the symbol with a copy of the environment map and thus allows dynamic and shared libraries to access the environment without being passed a copy. Would this be considered as a Linux-only alternative?What was the migration like? Were you able to only transform the implementation and maintain the overall API or?
Honestly don't recall (though yes, the API was changed, though only somewhat since the steps are the same: call a function to get the initial animation object, call
next()orcontinueon it). I know one of the animations was a PITA, but that's probably just because I was smooth brained and couldn't keep track of where the animation was doing what and how to cleanly turn it into a state machine. Before, After. (Yes, all terrible code, of which I'm deeply ashamed )))Woo! Congratulations on the release! Thanks to the team for all their hard work.
I'm super excited to kick the tires on the
std.Iointerface. Even ignoring the sexier justifications like addressing function coloring and swappable concurrency models, injecting IO just feels like the right way to do things. Isolating effects isn't just for the functional peeps ;) . I can't wait for the ergonomic debugging and testing capabilities this enables. Not having to awkwardly stub out any IO dependency just to test it is going to be a game changer for larger projects that need to ensure correctness."Juicy main" is a huge quality of life improvement. Not having to set up an allocator and do all this preamble when writing a quick program is great. I expect it will help many more people get into the language. I imagine the juggling to set up the debug allocator right upfront was just enough friction for people to bounce off before they actually got into things.
Was surprised to see the "Forbid Trivial Local Address Returned from Functions" section which is awesome...but more importantly it hides a link to planned work to also error on returned local references! I don't think I've run into these issues in years, but I definitely did starting out. I imagine that'll go a long way for anyone hesitant about Zig's safety story.
Agree, when I was a junior I kept bugging seniors about how to test code that does I/O. Their consistent response was basically "wrap the world in your own interface and pass it in". Then it is mockable, testable, etc. That always seemed so wrong to me. Turns out all languages before Zig just did it wrong and having your stdlib designed to pass I/O in is indeed the right way.
Edit: of course even without the language stdlib supporting you like Zig, software design concepts like "functional core / imperative shell" would have been helpful from the seniors.
The 'Juicy Main' bit is interesting. I don't think I've seen this approach taken to this level. I know that in C/C++ you can optionally have
argcandargv(apparentlyenvpis implementation defined) and in Austral, you can optionally have aRootCapability. Are there other examples of this (besides languages doing the C/C++ thing)?Ooh, juicy main looks great. That'll cut down on a lot of the boilerplate when starting a new program. I was literally thinking earlier "I'd like to start a new zig program, ugh gotta start by cutting and pasting some boilerplate from my other programs".
for me this is one of the most exciting new features of this version. have been playing around with it on master for a few weeks and have been delighted
Depends which part you mean: if you're thinking about changing the parameters of
mainthat "something" then introspects and calls it with the right parameters. Raku does CLI argument parsing this way.I should use Zig just for the cute mascots.
Zig is undergoing a lot of churn. I am not really seeing a rhyme or reason for most of it.
I used to use it, but I got sick of re-writing my programs - so at this point I think I'll wait until Zig 1.0, which is realistically some time next decade.
I've been following along since Zig 0.11 or so, and it does sometimes feel like churn but most of the improvements are for the better, and you gain new features along the way. I ported a large codebase to Zig 0.16 and it's quite approachable.
I'm really liking where things are going.
You can always leave old programs using old versions of Zig. Things like the Zig Version Manager make it easy to use multiple versions. I do suggest using more recent stuff to get all the latest goodies they've been cooking up.
I wonder if a Zig equivalent of tools like gofix or 2to3 would be possible or useful. Some of the churn seems amenable to automatic fixups, such as the new
@builtins.The cancellation part looks extremely interesting this is something that rust definitely struggles with. I don’t completely understand the section here. Do they drive the future to completion and disregard the result if you cancel? How do they prevent things like futurelock or just general issues caused by a canceled future effecting other parts of the code in unexpected ways
I am probably not qualified to answer this, and responding in hope that if I am understanding it incorrectly someone will correct me so I can learn something.
most (all?) IO calls can return
error.Canceled. when a task is cancelled, the task chugs along until the next call to such a method. the task can choose to do whatever it wants with that information: cleanup, ignore it, stop immediately. once the error is handed to the task, however, the canceled flag on that task is reset. if it wants to, it can recancel itself to propagate cancellation onward.there's also "cancel protection", which is I think critical in preventing futurelock by giving the task the ability to clean up properly.
so cancellations are requested, can be respected or ignored, and the future locking is prevented because they get to cleanup while protecting from more cancellation.
I had a conversation with Andrew at some point about how syscalls are interrupted, but it was slightly over my head.
These questions are difficult for me to answer because despite implementing async/await in Zig 4 different times in 4 different ways over the last 10 years, every time I've tried to understand the way async works in Rust I have failed to develop a coherent mental model for it.
To the best of my understanding, there's no such thing as "futurelock" in Zig, and none of the other footguns with Rust async, because it works fundamentally differently. When you async something in Zig, it starts happening right away. It doesn't get "polled" later by an "executor" or whathaveyou.
From the notes:
The art next to the post is really nice.
https://ziglang.org/img/Carmen_4.svg
https://ziglang.org/img/Ziggy_11.svg
https://ziglang.org/img/Carmen_8.svg
Art by https://heyitsjaki.com/
Got my work cut out for me to upgrade all my projects from 0.15.2. The biggest one being gdzig 😨
Oh FINALLY. This is (in my opinion) one of the ugliest parts of game/graphics programming in zig. There’s an example in the release notes but I think a before & after makes it clearer:
Before:
After:
Oh that’s so much better. It’ll even help with my window manager some just w.r.t. scaling certain buffers.
The integer and float casting improvements are all very neat:
const f: f64 = @sqrt(@floatFromInt(N))const a: u8 = @round(f)Things like this were always a pain in the neck for me, since my main Zig project is a little roguelike. I'm sure it's not what folks think of when you say "game development" (I'd call it "lite game development" instead), but it helps all the same! Can't wait to see what other ergonomic improvements make it out.
I'm also happy to see the
Futuretype and general async being added to the language again, even if it's only in the standard library. In the past I (ab)used async to produce generators, which I used heavily for things like animations and such. Those animations became 1.5-2x code when I had to convert them to a state machine, so I look forward to seeing if the new async system is capable of the same thing.I recall that
glibchas a nonstandard extension where, if a certain symbol is defined,glibccalls the symbol with a copy of the environment map and thus allows dynamic and shared libraries to access the environment without being passed a copy. Would this be considered as a Linux-only alternative?What was the migration like? Were you able to only transform the implementation and maintain the overall API or?
Honestly don't recall (though yes, the API was changed, though only somewhat since the steps are the same: call a function to get the initial animation object, call
next()orcontinueon it). I know one of the animations was a PITA, but that's probably just because I was smooth brained and couldn't keep track of where the animation was doing what and how to cleanly turn it into a state machine. Before, After. (Yes, all terrible code, of which I'm deeply ashamed )))Woo! Congratulations on the release! Thanks to the team for all their hard work.
I'm super excited to kick the tires on the
std.Iointerface. Even ignoring the sexier justifications like addressing function coloring and swappable concurrency models, injecting IO just feels like the right way to do things. Isolating effects isn't just for the functional peeps ;) . I can't wait for the ergonomic debugging and testing capabilities this enables. Not having to awkwardly stub out any IO dependency just to test it is going to be a game changer for larger projects that need to ensure correctness."Juicy main" is a huge quality of life improvement. Not having to set up an allocator and do all this preamble when writing a quick program is great. I expect it will help many more people get into the language. I imagine the juggling to set up the debug allocator right upfront was just enough friction for people to bounce off before they actually got into things.
Was surprised to see the "Forbid Trivial Local Address Returned from Functions" section which is awesome...but more importantly it hides a link to planned work to also error on returned local references! I don't think I've run into these issues in years, but I definitely did starting out. I imagine that'll go a long way for anyone hesitant about Zig's safety story.
Agree, when I was a junior I kept bugging seniors about how to test code that does I/O. Their consistent response was basically "wrap the world in your own interface and pass it in". Then it is mockable, testable, etc. That always seemed so wrong to me. Turns out all languages before Zig just did it wrong and having your stdlib designed to pass I/O in is indeed the right way.
Edit: of course even without the language stdlib supporting you like Zig, software design concepts like "functional core / imperative shell" would have been helpful from the seniors.
The 'Juicy Main' bit is interesting. I don't think I've seen this approach taken to this level. I know that in C/C++ you can optionally have
argcandargv(apparentlyenvpis implementation defined) and in Austral, you can optionally have aRootCapability. Are there other examples of this (besides languages doing the C/C++ thing)?Ooh, juicy main looks great. That'll cut down on a lot of the boilerplate when starting a new program. I was literally thinking earlier "I'd like to start a new zig program, ugh gotta start by cutting and pasting some boilerplate from my other programs".
for me this is one of the most exciting new features of this version. have been playing around with it on master for a few weeks and have been delighted
Depends which part you mean: if you're thinking about changing the parameters of
mainthat "something" then introspects and calls it with the right parameters. Raku does CLI argument parsing this way.I should use Zig just for the cute mascots.
Zig is undergoing a lot of churn. I am not really seeing a rhyme or reason for most of it.
I used to use it, but I got sick of re-writing my programs - so at this point I think I'll wait until Zig 1.0, which is realistically some time next decade.
I've been following along since Zig 0.11 or so, and it does sometimes feel like churn but most of the improvements are for the better, and you gain new features along the way. I ported a large codebase to Zig 0.16 and it's quite approachable.
I'm really liking where things are going.
You can always leave old programs using old versions of Zig. Things like the Zig Version Manager make it easy to use multiple versions. I do suggest using more recent stuff to get all the latest goodies they've been cooking up.
I wonder if a Zig equivalent of tools like gofix or 2to3 would be possible or useful. Some of the churn seems amenable to automatic fixups, such as the new
@builtins.The cancellation part looks extremely interesting this is something that rust definitely struggles with. I don’t completely understand the section here. Do they drive the future to completion and disregard the result if you cancel? How do they prevent things like futurelock or just general issues caused by a canceled future effecting other parts of the code in unexpected ways
I am probably not qualified to answer this, and responding in hope that if I am understanding it incorrectly someone will correct me so I can learn something.
most (all?) IO calls can return
error.Canceled. when a task is cancelled, the task chugs along until the next call to such a method. the task can choose to do whatever it wants with that information: cleanup, ignore it, stop immediately. once the error is handed to the task, however, the canceled flag on that task is reset. if it wants to, it can recancel itself to propagate cancellation onward.there's also "cancel protection", which is I think critical in preventing futurelock by giving the task the ability to clean up properly.
so cancellations are requested, can be respected or ignored, and the future locking is prevented because they get to cleanup while protecting from more cancellation.
I had a conversation with Andrew at some point about how syscalls are interrupted, but it was slightly over my head.
These questions are difficult for me to answer because despite implementing async/await in Zig 4 different times in 4 different ways over the last 10 years, every time I've tried to understand the way async works in Rust I have failed to develop a coherent mental model for it.
To the best of my understanding, there's no such thing as "futurelock" in Zig, and none of the other footguns with Rust async, because it works fundamentally differently. When you async something in Zig, it starts happening right away. It doesn't get "polled" later by an "executor" or whathaveyou.
From the notes:
The art next to the post is really nice.
https://ziglang.org/img/Carmen_4.svg
https://ziglang.org/img/Ziggy_11.svg
https://ziglang.org/img/Carmen_8.svg
Art by https://heyitsjaki.com/
Got my work cut out for me to upgrade all my projects from 0.15.2. The biggest one being gdzig 😨