How can I make interface functions to suspend func...
# coroutines
c
How can I make interface functions to suspend function? for example,
Copy code
interface BaseClass{
    fun foo()
    fun bar()
}
Copy code
class ChildClass: BaseClass {
    override fun foo()
    override fun bar()
}
My expectation is,
Copy code
class ChildClass: BaseClass {
    override suspend fun foo()
    override suspend fun bar()
}
Is that possible?
h
Copy code
interface BaseClass{
    suspend fun foo()
    suspend fun bar()
}
c
then every child class will override suspend fun funtions.
h
Yes. You can't override a non-suspend function with a suspend function and vice-versa.
c
You cannot call
suspend
functions from regular functions. Imagine if you could do what you wanted:
Copy code
fun main() { // non-suspend main
    val a: BaseClass = ChildClass()

    // we're calling the 'a' function of the base class, which is not suspend, that's OK
    a.foo()
}
What would happen? It can't call the overriden function, because it's
suspend
and we're in a function where
suspend
is not allowed.
j
To put it more plainly, a
suspend
function technically has a different signature (in bytecode), so it's not a valid override for a non-suspend function
then every child class will override suspend fun funtions
@chanjungskim What is the problem with this?
c
@Joffrey that's true, but it makes it seem like it's a technical limitation of coroutines, whereas it's on purpose because it wouldn't make sense even if it was possible to make it compatible in bytecode
j
Right. It was not my intention to convey that idea, so you're right that it might not be the best angle to explain this 😅
A more correct explanation is that a
suspend
function has a different contract from a regular function
c
(more generally, this concept of "contract" is called "code coloring", if anyone is interested by the broader theory)
k
c
Well, still I don't understand why it's not possible. I am actually implementing logger with Slack webhook and Datadog. I wanted to create a common parent class for making them interchangeable. Datadog uses async call under the hood. But my custom webhook doesn't. using suspend function has no problem with calling normal function like Datadog but, that can be confusing if Datadog use supend function because it doesn't need suspend actually.
c
It’s not usually confusing to override a
suspend
function and then never suspend within it, any more than overriding a function and ignoring parameters passed to it that you don’t need. But it communicates that the code is intended to run async, may be running on background threads rather than the main thread, and helps with handling errors thrown within it. So even if you’re not strictly calling any
suspend
functions within the Datadog implementation, there is still usefulness to having the method marked suspend
c
suspend
functions are colored differently than regular functions, they can never be compatible. You want to create a common ancestor, but synchronous and asynchronous are very different things.
u
@Casey Brooks even though it is fine for a suspend function not to suspend, it is not ok to block in a suspend function. The implicit contract of a suspend function is to not block the current thread but to suspend (and potentially schedule to another thread for blocking)
j
@uli true, but that is not very confusing for implementers of the interface with
suspend
methods. Technically they are aware of the
suspend
keyword and should implement the function accordingly (at least with some
withContext()
to dispatch to another thread)
539 Views