authorgravatar for bnprks@users.noreply.github.combnprks <bnprks@users.noreply.github.com> 2021-06-09 00:37:07-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-08-20 14:16:04+03:00
logcfb2827b0a9efaf3937db27dbe3352cbb612466b
treebc18678f1754d2f8a8010f99eb789e11baec0920
parent0cecdca6a24d5009d543962f62c907aa45ec82ff

Clarify async/await language documentation.

The async/await documentation was somewhat hard for me to follow when first learning. Two particular sticking points were 1. The alphabet example constructing the string "abcdefghi" breaks the stated rule that every async has a matching await. 2. It was somewhat unclear to me what the rules for control flow were around async/await constructs. I've tried to improve this documentation with some minimal explanatory edits, which are correct to the best of my beginner's understanding & experimentation.

1 files changed, 20 insertions(+), 4 deletions(-)

doc/langref.html.in+20-4
...@@ -6645,14 +6645,21 @@ test "global assembly" {...@@ -6645,14 +6645,21 @@ test "global assembly" {
6645 <p>6645 <p>
6646 When a function is called, a frame is pushed to the stack,6646 When a function is called, a frame is pushed to the stack,
6647 the function runs until it reaches a return statement, and then the frame is popped from the stack.6647 the function runs until it reaches a return statement, and then the frame is popped from the stack.
6648 At the callsite, the following code does not run until the function returns.6648 The code following the callsite does not run until the function returns.
6649 </p>6649 </p>
6650 <p>6650 <p>
6651 An async function is a function whose callsite is split into an {#syntax#}async{#endsyntax#} initiation,6651 An async function is a function whose execution is split into an {#syntax#}async{#endsyntax#} initiation,
6652 followed by an {#syntax#}await{#endsyntax#} completion. Its frame is6652 followed by an {#syntax#}await{#endsyntax#} completion. Its frame is
6653 provided explicitly by the caller, and it can be suspended and resumed any number of times.6653 provided explicitly by the caller, and it can be suspended and resumed any number of times.
6654 </p>6654 </p>
6655 <p>6655 <p>
6656 The code following the {#syntax#}async{#endsyntax#} callsite runs immediately after the async
6657 function first suspends. When the return value of the async function is needed,
6658 the calling code can {#syntax#}await{#endsyntax#} on the async function frame.
6659 This will suspend the calling code until the async function completes, at which point
6660 execution resumes just after the {#syntax#}await{#endsyntax#} callsite.
6661 </p>
6662 <p>
6656 Zig infers that a function is {#syntax#}async{#endsyntax#} when it observes that the function contains6663 Zig infers that a function is {#syntax#}async{#endsyntax#} when it observes that the function contains
6657 a <strong>suspension point</strong>. Async functions can be called the same as normal functions. A6664 a <strong>suspension point</strong>. Async functions can be called the same as normal functions. A
6658 function call of an async function is a suspend point.6665 function call of an async function is a suspend point.
...@@ -6755,7 +6762,14 @@ fn testResumeFromSuspend(my_result: *i32) void {...@@ -6755,7 +6762,14 @@ fn testResumeFromSuspend(my_result: *i32) void {
6755 {#header_open|Async and Await#}6762 {#header_open|Async and Await#}
6756 <p>6763 <p>
6757 In the same way that every {#syntax#}suspend{#endsyntax#} has a matching6764 In the same way that every {#syntax#}suspend{#endsyntax#} has a matching
6758 {#syntax#}resume{#endsyntax#}, every {#syntax#}async{#endsyntax#} has a matching {#syntax#}await{#endsyntax#}.6765 {#syntax#}resume{#endsyntax#}, every {#syntax#}async{#endsyntax#} has a matching {#syntax#}await{#endsyntax#}
6766 in standard code.
6767 </p>
6768 <p>
6769 However, it is possible to have an {#syntax#}async{#endsyntax#} call
6770 without a matching {#syntax#}await{#endsyntax#}. Upon completion of the async function,
6771 execution would continue at the most recent {#syntax#}async{#endsyntax#} callsite or {#syntax#}resume{#endsyntax#} callsite,
6772 and the return value of the async function would be lost.
6759 </p>6773 </p>
6760 {#code_begin|test#}6774 {#code_begin|test#}
6761const std = @import("std");6775const std = @import("std");
...@@ -6790,7 +6804,9 @@ fn func() void {...@@ -6790,7 +6804,9 @@ fn func() void {
6790 </p>6804 </p>
6791 <p>6805 <p>
6792 {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that6806 {#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
6793 coerces to {#syntax#}anyframe->T{#endsyntax#}.6807 coerces to {#syntax#}anyframe->T{#endsyntax#}. Calling {#syntax#}await{#endsyntax#} on
6808 the frame of an async function will cause execution to continue at the
6809 {#syntax#}await{#endsyntax#} callsite once the target function completes.
6794 </p>6810 </p>
6795 <p>6811 <p>
6796 There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.6812 There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.