Structured concurrency

Asynchronous operations

Suppose that you are writing a front-end UI application (mobile, web, or desktop — it does not matter for this example) and you need to perform a request to your backend to fetch some data and update your UI model with the result of it. Our original recommendation was to write it like this:

fun requestSomeData() {
launch(UI) {
updateUI(performRequest())
}
}
fun requestSomeData() {
launch {
updateUI(performRequest())
}
}

Parallel decomposition

I’ve given numerous talks on Kotlin coroutines, presenting the following sample code that shows how to load two images in parallel and combine them later — an idiomatic example of parallel decomposition of work with Kotlin coroutines:

suspend fun loadAndCombine(name1: String, name2: String): Image { 
val deferred1 = async { loadImage(name1) }
val
deferred2 = async { loadImage(name2) }
return
combineImages(deferred1.await(), deferred2.await())
}
suspend fun loadAndCombine(name1: String, name2: String): Image =
coroutineScope {
val deferred1 = async { loadImage(name1) }
val
deferred2 = async { loadImage(name2) }
combineImages(deferred1.await(), deferred2.await())
}

Further reading

The concept structured concurrency has more philosophy behind it. I highly recommend to read “Notes on structured concurrency, or: Go statement considered harmful” that establishes good analogy between a classic goto-statement vs structured programming debate and a modern world where languages just start to give us a way to launch concurrent asynchronous tasks in a completely non-structured way. It has to end.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store