Daniel Lew
October 13, 2020
410

# Grokking Coroutines (MinneBar)

What are coroutines, really?

Given at MinneBar 2020.

October 13, 2020

## Transcript

1. Grokking Coroutines
@danlew42

2. “Essentially, coroutines are light-weight
~Kotlin Documentation

3. myScope.launch {
displayImage(image)
}
suspend fun downloadImage() = withContext(Dispatchers.IO) { … }
fun displayImage(image: Image)

4. sequence {
var cur = 1
var next = 1
while (true) {
yield(cur)
val tmp = cur + next
cur = next
next = tmp
}
}

5. What are coroutines?

6. Subroutines
fun sumSquaredValues(values: List): Int {
return values.sumBy { value ->
square(value)
}
}
fun square(value: Int): Int = value * value

7. Routine Subroutine

8. Coroutine Coroutine

9. val iterator = sequence.iterator()
while (iterator.hasNext()) {
val next = iterator.next()
println(next)
}
sequence {
var cur = 1
var next = 1
while (true) {
yield(cur)
val tmp = cur + next
cur = next
next = tmp
}
}
Consumer Producer

10. val iterator = sequence.iterator()
while (iterator.hasNext()) {
val next = iterator.next()
println(next)
}
sequence {
var cur = 1
var next = 1
while (true) {
yield(cur)
val tmp = cur + next
cur = next
next = tmp
}
}
Consumer Producer

11. class Fibonacci {
var cur = 1
var next = 1
fun next(): Int {
val toReturn = cur
val tmp = cur + next
cur = next
next = tmp
}
}
sequence {
var cur = 1
var next = 1
while (true) {
yield(cur)
val tmp = cur + next
cur = next
next = tmp
}
}
Versus

12. Multiple Suspend Points
sequence {
yield(1) // first Fibonacci number
var cur = 1
var next = 1
while (true) {
yield(next) // next Fibonacci number
val tmp = cur + next
cur = next
next = tmp
}
}

13. Why use coroutines?

14. Why use coroutines?
• Another tool for writing good code

• Two ways to use tool:

• Code Structure

• Concurrency

15. https://www.ﬂickr.com/photos/117693452@N04/12547460924

17. Blocking Functions
fun main() {
print(calculateMeaningOfLife())
}
fun calculateMeaningOfLife(): Int {
// Calculates for 7.5 million years, then...
return 42
}

18. Non-Blocking Function
suspend fun calculateMeaningOfLife(): Int {
delay(7.5 million years)
return 42
}

19. Blocking vs. Nonblocking
Blocking Blocked During I/O
Non-Blocking
Waiting During I/O
Doing other work

suspend fun task(name: String, delay: Long) {
joinAll(
async { doSomething("First", 10) },
async { doSomething("Second", 5) }
)
}
suspend fun doSomething(name: String, delay: Long) {
delay(delay)
}
First START (main)
Second START (main)
Second END (main)
First END (main)

Coroutines == cooperative multitasking

22. Callback Hell
requestRandomUrl { url ->
displayImage(image)
}
}
myScope.launch {
val url = requestRandomUrl()
displayImage(image)
}
Vs

23. Why use coroutines?
• Concurrency

• Coroutines *are* like light-weight threads!

• …In any language!

• Code Structure

• Coroutines enable simpler code

24. Kotlin Coroutines

25. kotlin.coroutines
(stdlib)
kotlinx.coroutines
(library)

26. kotlin.coroutines
(stdlib)
kotlinx.coroutines
(library)

27. Stdlib Basics
• Suspending functions

• A way to start suspending functions

• Contexts

28. Suspend Keyword

29. Start Suspending Functions
suspend fun mySuspendingFunction()
fun (suspend () -> T).startCoroutine(completion: Continuation)
fun main() {
::mySuspendingFunction.startCoroutine(
Continuation(EmptyCoroutineContext) { }
)
}

30. Coroutine Context
• Store useful info about coroutine

• Dispatcher

• Job

• Debug info

31. Coroutine Library

32. myScope.launch {
displayImage(image)
}
suspend fun downloadImage() = withContext(Dispatchers.IO) { … }
fun displayImage(image: Image)

33. myScope.launch {
displayImage(image)
}
suspend fun downloadImage() = withContext(Dispatchers.IO) { … }
fun displayImage(image: Image)

34. myScope.launch {
displayImage(image)
}
suspend fun downloadImage() = withContext(Dispatchers.IO) { … }
fun displayImage(image: Image)

35. myScope.launch {
displayImage(image)
}
suspend fun downloadImage() = withContext(Dispatchers.IO) { … }
fun displayImage(image: Image)

36. Review
• Coroutines are suspending functions

• Suspending functions are useful for concurrency

• Kotlin stdlib provides coroutine support

• Kotlin coroutine library adds practical functions for coroutines