# 5.5.2 Implementation of Coroutines

## Implementation of Coroutines

Here is a basic example of a function built with coroutines:&#x20;

```kotlin
val job = GlobalScope.launch {
    delay(1000L)
    println("World!")
}
println("Hello,")
job.join() // waits until the job is completed before it outputs 

// Output: 
// Hello, 
// World 
```

As we see from the example, `job` is a coroutine that we declare first, but it does not output until we call `job.join()`. This allows us to run functions ahead of time and only output them when needed.&#x20;

The issue with the code above is that it uses `GlobalScope`, which acts like a top-level thread. If the code inside of the `GlobalScope` consumes a lot of resources, we don't want the operation to run at the top-level in case it blocks the rest of the app from functioning. Instead, we want to be using `CoroutineScope.`&#x20;

In the example below, we'll present a code block that uses `CoroutineScope` as well as two different functions `launch {...}` and `runBlocking {...}`. Both `runBlocking` and `coroutineScope` will create a new coroutine scope and waits for its children to finish before completing; however, the difference is that `runBlocking` will **block** operations until it finishes and `coroutineScope` only **suspends**, thus allowing other functions to use the thread.&#x20;

```kotlin
fun main() = runBlocking { // Creates coroutine scope A
    launch { // Creates coroutine scope B
        delay(200L)
        println("Task from runBlocking")
    }
    
    coroutineScope { // Creates a coroutine scope C
        launch { // Creates a coroutine scope D
            delay(500L) 
            println("Task from nested launch")
        }
    
        delay(100L)
        println("Task from coroutine scope") 
    }
    
    println("Coroutine scope is over") 
}
// Output: 
// Task from coroutine scope
// Task from runBlocking
// Task from nested launch
// Coroutine scope is over
```

In the example above, we can see that the `runBlocking` forces the app to block on `main()` until all its operations are completed. We can also see that code from **coroutine scope C** starts to run before suspending and allowing the code within **coroutine scope B** to complete and returning to the nested coroutine scope within **C**.&#x20;

Coroutines are extremely powerful in this sense because you can theoretically run thousands of coroutines at the same time, and the app won't crash.&#x20;

```kotlin
suspend fun main() {
    coroutineScope {
        repeat(1_000) { 
            launch { functionA() }
        }
    }
}

// Output: 
// functionA will run 1000 times. 
```

## Implementation with Suspending Functions

Generally, we want to be creating suspending functions to free up space in memory and allow the processors to determine which functions to complete first (unless there is a need for blocking functions). Below is an example on how to build a suspending function:&#x20;

```kotlin
fun main() = runBlocking {
    launch { functionA() }
    println("Hello,")
}

suspend fun functionA() { // keyword suspend is important
    delay(1000L)
    println("World!")
}

// Output: 
// Hello, 
// World!
```

In the example above, we use the keyword `suspend` to specify our suspending function. We can see from the example that code in the outer scope of `runBlocking` is ran first before the code inside of `launch` due to suspension.&#x20;
