Simple problem with an API (from Vert.x), which uses coroutines


#1

I have the following function declaration:

suspend fun <T> Context.executeBlockingAwait(blockingCodeHandler : Handler<Future<T>>) : T? {

with

@FunctionalInterface
public interface Handler<E> {

    /**
     * Something has happened, so handle it.
     *
     * @param event  the event to handle
     */
    void handle(E event);
}

I don’t get this compiled :frowning:

private suspend fun foo(ctx: Context) {
    ctx.executeBlockingAwait { fut ->
        fut.complete("")
    }
}

Type mismatch. Required: Handler<Future<String>> Found: (???) → [ERROR : ]

Also not with:

context.executeBlockingAwait<String> { future: Future<String> ->
    future.complete("bar")
}

Type mismatch. Required: Handler<Future<String>> Found: (Future<String>) → Unit

Isn’t this exactly how a handler should look like? Hmmm, I sadly don’t get it.


#3

So

private suspend fun foo(ctx: Context) {
    ctx.executeBlockingAwait { fut ->
        fut.complete("")
        ""
    }
}

I thought that’s the return value from executeBlockingAwait(…)?

I’m getting

Type mismatch. Required: Handler<Future<???>> Found: (???) → String

But I thought I’m passing in the higher function, which is the Handler, and the handler has no return value (void). I forgot to mention that it’s a Java functional interface, but it might be obvious.


#4

That said, the API would be super strange :wink:


#5

I may have been too hasty. Future may not be what I expected.


#6

Ist’s a Vert.x Future but just like a Promise/Future.


#7

What happens if you try something along this line?

    private suspend fun foo(ctx: Context) {
        val s: String? = ctx.executeBlockingAwait(object : Handler<Future<String>> {
            override fun handle(event: Future<String>) {
                return event.complete("")
            }
        })
    }

#8

Strange thing, okay it works, but what is this?

val s: String? = ctx.executeBlockingAwait(Handler<Future<String>> { event -> event.complete("") })

IntelliJ says it should be converted to a lambda… is this Handler<Future<String>> something like a cast, because the type inference rules don’t work? Maybe because of Java?


#9

I don’t have Vert.X so I just mimicked the interfaces you gave and wrote it up in Android Studio. I don’t have the same code you do, so had to make a few guesses.

From what I’ve gleaned both Handler, and Future can take type parameters of Any, so you need to help it along by being more specific. I’ll see if I can get something official to reference.


#10

They just somehow generated these suspending extension methods, so I’m not sure. It’s in their 3.6.0-SNAPSHOT version and I’ve already posted on their mailing list a few days ago. I guess their intent was that one can use it with a simple lambda.

BTW: As I’m rather new to Kotlin, I currently don’t know what this explicit Handler<Future<String>> { ... } means. Is it meant as a shortcut for anonymous classes with an explicit type for the lambda?


#11

https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions


#12

Oh okay, they (the Vert.x guys) need to change this, I think It’s rather ugly… and thank you :slight_smile: