Kotlinx.coroutines: Add function to convert Deferred to suspending function

Created on 5 Sep 2019  路  4Comments  路  Source: Kotlin/kotlinx.coroutines

I have been debating about whether it's better to inject Deferred<T> or suspend () -> T into my classes. The reason I've recently leaned to Deferred<T> is I want to avoid allocating an extra anonymous inner class to convert Deferred<T> to suspend () -> T.

Now, I could create my own fun <T> Deferred<T>.asFunction(): suspend () -> T to share, but I think this would be useful to add to the standard lib because I imagine many people may use it.

I think suspend () -> T should be preferred over Deferred<T> because the latter exposes the Job API (which can be cancelled, and is therefore not read-only). Adding fun <T> Deferred<T>.asFunction(): suspend () -> T to the standard lib may help encourage this behavior.

Example is below:

typealias GetIsUserAGoat = suspend () -> Boolean

@Suppress("FunctionName")
fun GetIsUserAGoat(scope: CoroutineScope): GetIsUserAGoat {
    return scope.async {
        true // pretend this is asynchronously fetched
    }
        .asFunction()
}

// add something like this to standard lib
fun <T> Deferred<T>.asFunction(): suspend () -> T = ::await
design

Most helpful comment

It does create a separate class, yet I am not sure that the case for "reusing" this class with a dedicated one-line asFunction extension deserves it. We do not encourage the use of Deferred class in the first place.

All 4 comments

Thanks for this proposal. Do you need a separate function for this, though? You can always use ::await to convert deferred to a function. Also, if you don't use Deferred in the first place, you would need a conversion.

Do you need a separate function for this, though? You can always use ::await to convert deferred to a function

If ::await does not create an anonymous inner class//additional class file in bytecode, then maybe less so. I want it to be trivial to convert Deferred<T> into suspend () -> T

It does create a separate class, yet I am not sure that the case for "reusing" this class with a dedicated one-line asFunction extension deserves it. We do not encourage the use of Deferred class in the first place.

R8 _should_ de-duplicate the classes that are created for that function reference. It'll do it for lambdas, but I need to confirm it works with a bound function reference.

Was this page helpful?
0 / 5 - 0 ratings