Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Kotlin, what's the difference between the terms Coroutine and Continuation?

It seems like these two terms are used interchangeably. Yet, there also seems to be some difference that I'm struggling to put my finger on. Is there a difference?

like image 417
Julian A. Avatar asked May 30 '18 07:05

Julian A.


People also ask

What is a Continuation Kotlin?

A continuation is the implicit parameter that the Kotlin compiler passes to any suspend function when compiling it. It is represented by a basic contract: interface Continuation<in T> { abstract val context: CoroutineContext abstract fun resumeWith(result: Result<T>) }

What is a coroutine in Kotlin?

A coroutine is a concurrency design pattern that you can use on Android to simplify code that executes asynchronously. Coroutines were added to Kotlin in version 1.3 and are based on established concepts from other languages.

What is the difference between launch and async in Kotlin coroutines?

Kotlin launch vs async coroutinesThe launch launches a new coroutine concurrently with the rest of the code, which continues to work independently. The async creates a coroutine and can return the result of the asynchronous task. Start a coroutine that returns some result.

What are coroutines used for?

Coroutines are computer program components that generalize subroutines for non-preemptive multitasking, by allowing execution to be suspended and resumed. Coroutines are well-suited for implementing familiar program components such as cooperative tasks, exceptions, event loops, iterators, infinite lists and pipes.


2 Answers

It's true, these two are quite closely related. To resume a coroutine, you actually call continuation.resume().

Each coroutine has its associated continuation object. Actually, you don't need anything else but that object, it contains the complete state of the coroutine.

To a certain degree, Kotlin uses "coroutine" to also include the coroutine context, which gives the coroutine the knowledge how exactly to suspend itself, where to keep the continuation while suspended, and how to resume (dispatch) it later. But you can also use the Unconfined coroutine context, which is almost as good as no context at all, and be in total control of resumption with nothing but the continuation object being preserved:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

var continuation: Continuation<Unit>? = null

fun main(args: Array<String>) {
    GlobalScope.launch(Dispatchers.Unconfined) {
        println("Suspending")
        suspendCoroutine<Unit> { cont ->
            continuation = cont
        }
        println("Resumed!")
    }
    println("After launch")
    continuation!!.resume(Unit)
    println("After continuation.resume(Unit)")
}

Here you can see that we reproduced the whole suspend-resume scenario while keeping nothing but the Continuation object.

My conclusion is that, due to the features of Kotlin's coroutine design (especialy the fact that they are stackless), there's a blurry line between the concepts of "coroutine" and "continuation".

like image 86
Marko Topolnik Avatar answered Sep 19 '22 22:09

Marko Topolnik


Coroutines are procedures that take turns doing their task and then suspend to give control to the other coroutines in the group, and resume task.

Continuation is the stack that controls the flow of the program, that allows it to skip into different parts of your program. You could use it to control the flow including coroutine like a global switch.

like image 27
hatched Avatar answered Sep 16 '22 22:09

hatched