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
Roman Elizarov

Roman Elizarov

Project Lead for the Kotlin Programming Language @JetBrains