Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/common/src/CoroutineScope.kt (Kotlin)

Code before:
/**
 * Creates the main [CoroutineScope] for UI components.
 *
 * Example of use:
 * ```
 * class MyAndroidActivity {
 *     private val scope = MainScope()
 *
 *     override fun onDestroy() {
 *         super.onDestroy()
 *         scope.cancel()
 *     }
 * }
 * ```
 *
 * The resulting scope has [SupervisorJob] and [Dispatchers.Main] context elements.
 * If you want to append additional elements to the main scope, use [CoroutineScope.plus] operator:
 * `val scope = MainScope() + CoroutineName("MyActivity")`.
 */
@Suppress("FunctionName")
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)

/**
 * Returns `true` when the current [Job] is still active (has not completed and was not cancelled yet).
 *
 * A coroutine cancallation [is cooperative](https://kotlinlang.org/docs/cancellation-and-timeouts.html#cancellation-is-cooperative)
 * and normally, the cancellation machinery happens when the coroutine *suspends*, for example,
 * when trying to read from a [channel][kotlinx.coroutines.channels.Channel] that is empty.
 *
 * Sometimes, a coroutine does not need to do any of such operations, but still wants to be a cooperative
 * and respect cancellation.
 *
 * [isActive] property is inteded to be used for scenarios like this:
 * ```
 * val watchdogDispatcher = Dispatchers.IO.limitParallelism(1)
 * fun backgroundWork() {
 *     println("Doing bookkeeping in the background in a non-suspending manner")
 *     Thread.sleep(100L) // Sleep 100ms
 * }
 * // Part of some non-trivial CoroutineScope-confined lifecycle
 * launch(watchdogDispatcher) {
 *     while (isActive) {
 *         // Repetitively do some background work that is non-suspending
 *         backgroundWork()
 *     }
 * }
 * ```
 *
 * This function returns `true` if there is no [job][Job] in the scope's [coroutineContext][CoroutineScope.coroutineContext].
 * This property is a shortcut for `coroutineContext.isActive` in the scope when
 * [CoroutineScope] is available.

Review comment (suggestion):
```suggestion
 * Coroutine cancallation [is cooperative](https://kotlinlang.org/docs/cancellation-and-timeouts.html#cancellation-is-cooperative)
```

The article changes the meaning from "coroutine cancellation (as a concept; in general; as a set of rules and behaviors) is cooperative" to "each instance of coroutine cancellation happens in a cooperative manner". Both are true, but I guess the first one is what was meant.

Code after:
/**
 * Creates the main [CoroutineScope] for UI components.
 *
 * Example of use:
 * ```
 * class MyAndroidActivity {
 *     private val scope = MainScope()
 *
 *     override fun onDestroy() {
 *         super.onDestroy()
 *         scope.cancel()
 *     }
 * }
 * ```
 *
 * The resulting scope has [SupervisorJob] and [Dispatchers.Main] context elements.
 * If you want to append additional elements to the main scope, use [CoroutineScope.plus] operator:
 * `val scope = MainScope() + CoroutineName("MyActivity")`.
 */
@Suppress("FunctionName")
public fun MainScope(): CoroutineScope = ContextScope(SupervisorJob() + Dispatchers.Main)

/**
 * Returns `true` when the current [Job] is still active (has not completed and was not cancelled yet).
 *
 * Coroutine cancallation [is cooperative](https://kotlinlang.org/docs/cancellation-and-timeouts.html#cancellation-is-cooperative)
 * and normally, it's checked if a coroutine is cancelled when it *suspends*, for example,
 * when trying to read from a [channel][kotlinx.coroutines.channels.Channel] that is empty.
 *
 * Sometimes, a coroutine does not need to perform suspending operations, but still wants to be cooperative
 * and respect cancellation.
 *
 * The [isActive] property is inteded to be used for scenarios like this:
 * ```
 * val watchdogDispatcher = Dispatchers.IO.limitParallelism(1)
 * fun backgroundWork() {
 *     println("Doing bookkeeping in the background in a non-suspending manner")
 *     Thread.sleep(100L) // Sleep 100ms
 * }
 * // Part of some non-trivial CoroutineScope-confined lifecycle
 * launch(watchdogDispatcher) {
 *     while (isActive) {
 *         // Repetitively do some background work that is non-suspending
 *         backgroundWork()
 *     }
 * }
 * ```
 *
 * This function returns `true` if there is no [job][Job] in the scope's [coroutineContext][CoroutineScope.coroutineContext].
 * This property is a shortcut for `coroutineContext.isActive` in the scope when
 * [CoroutineScope] is available.