Why is CoroutineScope.launch and Coroutine.async are extension functions instead of a member function of CoroutineScope?

565 views Asked by At

The title states my question.

What is exactly the reason why CoroutineScope.launch and Coroutine.async are just extension functions of CoroutineScope instead oa a member function?

What benefits does it provide?

I am asking because maybe the reason behind this design could be helpful in designing things in the future too.

Thank in advance.

3

There are 3 answers

0
Alexey Romanov On BEST ANSWER

launch and async are coroutine builders, but they aren't the only ones: look in integration modules for future (and another future), publish, the RxJava 2 builders etc. Obviously those can't be members of CoroutineScope, so why should launch and async be?

In addition, by being extension functions you know they don't rely on any CoroutineScope privates (well, they could rely on internals since they are in the same module).

0
functionaldude On

Mostly because with extension functions it is easier to structure your code in multiple modules even if it is represented as one class.

CoroutineScope is actually a really good example of this design pattern. Take a look at CoroutineScope.kt where the interface is declared. There is only basic functionality there (plus operator and cancel())

The two functions you mentioned are defined in Builders.common.kt. If You take a look at the contents of this file, you can see that there are multiple classes which are private, this means they can only be used in this file. This tells you right away that you don't need this these classes for the basic functionality which is designed in CoroutineScope.kt, they are only there for launch {...} and async {...}

So if you have a large class with multiple functionality, it makes sense to break it up in multiple files (=modules).

0
Eugene Petrenko On

The kotlinx.coroutines uses structural concurrency approach to make sure all errors are propagated to a parent coroutine. Similarly, a parent coroutine will by default wait for all it's child coroutines to complete.

There is a Job object associated with every coroutine when you do launch or async. It is just easier to use extension functions for that design to make it work implicitly, without a code-writer explicit attention

You may have a look at the more detailed explanation :

https://kotlinlang.org/docs/reference/coroutines/basics.html#structured-concurrency

https://medium.com/@elizarov/structured-concurrency-722d765aa952