Fix typos and article use, reword phrases in "Composing Suspending functions"
diff --git a/docs/composing-suspending-functions.md b/docs/composing-suspending-functions.md
index ed0d85c..a910f49 100644
--- a/docs/composing-suspending-functions.md
+++ b/docs/composing-suspending-functions.md
@@ -56,9 +56,9 @@
</div>
-What do we do if need to invoke them _sequentially_ -- first `doSomethingUsefulOne` _and then_
-`doSomethingUsefulTwo` and compute the sum of their results?
-In practice we do this if we use the results of the first function to make a decision on whether we need
+What do we do if we need them to be invoked _sequentially_ — first `doSomethingUsefulOne` _and then_
+`doSomethingUsefulTwo`, and compute the sum of their results?
+In practice we do this if we use the result of the first function to make a decision on whether we need
to invoke the second one or to decide on how to invoke it.
We use a normal sequential invocation, because the code in the coroutine, just like in the regular
@@ -110,12 +110,12 @@
### Concurrent using async
-What if there are no dependencies between invocation of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
+What if there are no dependencies between invocations of `doSomethingUsefulOne` and `doSomethingUsefulTwo` and
we want to get the answer faster, by doing both _concurrently_? This is where [async] comes to help.
Conceptually, [async] is just like [launch]. It starts a separate coroutine which is a light-weight thread
that works concurrently with all the other coroutines. The difference is that `launch` returns a [Job] and
-does not carry any resulting value, while `async` returns a [Deferred] -- a light-weight non-blocking future
+does not carry any resulting value, while `async` returns a [Deferred] — a light-weight non-blocking future
that represents a promise to provide a result later. You can use `.await()` on a deferred value to get its eventual result,
but `Deferred` is also a `Job`, so you can cancel it if needed.
@@ -161,14 +161,14 @@
<!--- TEST ARBITRARY_TIME -->
-This is twice as fast, because we have concurrent execution of two coroutines.
+This is twice as fast, because the two coroutines execute concurrently.
Note that concurrency with coroutines is always explicit.
### Lazily started async
-There is a laziness option to [async] using an optional `start` parameter with a value of [CoroutineStart.LAZY].
-It starts coroutine only when its result is needed by some
-[await][Deferred.await] or if a [start][Job.start] function
+Optionally, [async] can be made lazy by setting its `start` parameter to [CoroutineStart.LAZY].
+In this mode it only starts the coroutine when its result is required by
+[await][Deferred.await], or if its `Job`'s [start][Job.start] function
is invoked. Run the following example:
<div class="sample" markdown="1" theme="idea" data-min-compiler-version="1.3">
@@ -219,18 +219,18 @@
the programmer on when exactly to start the execution by calling [start][Job.start]. We first
start `one`, then start `two`, and then await for the individual coroutines to finish.
-Note that if we have called [await][Deferred.await] in `println` and omitted [start][Job.start] on individual
-coroutines, then we would have got the sequential behaviour as [await][Deferred.await] starts the coroutine
-execution and waits for the execution to finish, which is not the intended use-case for laziness.
+Note that if we just call [await][Deferred.await] in `println` without first calling [start][Job.start] on individual
+coroutines, this will lead to sequential behavior, since [await][Deferred.await] starts the coroutine
+execution and waits for its finish, which is not the intended use-case for laziness.
The use-case for `async(start = CoroutineStart.LAZY)` is a replacement for the
standard `lazy` function in cases when computation of the value involves suspending functions.
### Async-style functions
We can define async-style functions that invoke `doSomethingUsefulOne` and `doSomethingUsefulTwo`
-_asynchronously_ using [async] coroutine builder with an explicit [GlobalScope] reference.
-We name such functions with
-"Async" suffix to highlight the fact that they only start asynchronous computation and one needs
+_asynchronously_ using the [async] coroutine builder with an explicit [GlobalScope] reference.
+We name such functions with the
+"...Async" suffix to highlight the fact that they only start asynchronous computation and one needs
to use the resulting deferred value to get the result.
<div class="sample" markdown="1" theme="idea" data-highlight-only>
@@ -310,21 +310,21 @@
> This programming style with async functions is provided here only for illustration, because it is a popular style
in other programming languages. Using this style with Kotlin coroutines is **strongly discouraged** for the
-reasons that are explained below.
+reasons explained below.
-Consider what happens if between `val one = somethingUsefulOneAsync()` line and `one.await()` expression there is some logic
+Consider what happens if between the `val one = somethingUsefulOneAsync()` line and `one.await()` expression there is some logic
error in the code and the program throws an exception and the operation that was being performed by the program aborts.
Normally, a global error-handler could catch this exception, log and report the error for developers, but the program
-could otherwise continue doing other operations. But here we have `somethingUsefulOneAsync` still running in background,
-despite the fact, that operation that had initiated it aborts. This problem does not happen with structured
+could otherwise continue doing other operations. But here we have `somethingUsefulOneAsync` still running in the background,
+even though the operation that initiated it was aborted. This problem does not happen with structured
concurrency, as shown in the section below.
### Structured concurrency with async
-Let us take [Concurrent using async](#concurrent-using-async) example and extract a function that
+Let us take the [Concurrent using async](#concurrent-using-async) example and extract a function that
concurrently performs `doSomethingUsefulOne` and `doSomethingUsefulTwo` and returns the sum of their results.
-Because [async] coroutines builder is defined as extension on [CoroutineScope] we need to have it in the
-scope and that is what [coroutineScope] function provides:
+Because the [async] coroutine builder is defined as an extension on [CoroutineScope], we need to have it in the
+scope and that is what the [coroutineScope] function provides:
<div class="sample" markdown="1" theme="idea" data-highlight-only>
@@ -338,8 +338,8 @@
</div>
-This way, if something goes wrong inside the code of `concurrentSum` function and it throws an exception,
-all the coroutines that were launched in its scope are cancelled.
+This way, if something goes wrong inside the code of the `concurrentSum` function and it throws an exception,
+all the coroutines that were launched in its scope will be cancelled.
<!--- CLEAR -->
@@ -379,7 +379,7 @@
> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-compose-05.kt).
-We still have concurrent execution of both operations as evident from the output of the above main function:
+We still have concurrent execution of both operations, as evident from the output of the above `main` function:
```text
The answer is 42
@@ -426,7 +426,8 @@
> You can get full code [here](../kotlinx-coroutines-core/jvm/test/guide/example-compose-06.kt).
-Note, how both first `async` and awaiting parent are cancelled on the one child failure:
+Note how both the first `async` and the awaiting parent are cancelled on failure of one of the children
+(namely, `two`):
```text
Second child throws an exception
First child was cancelled