I have some type system head-scratching trying to ...
# general-advice
j
I have some type system head-scratching trying to figure it out. I want to wrap Java 7 Future into kotlin’s Deferred. There is a Java 8
CompletableFuture.asDeferred()
already, but when the API you’re using is still java7-compatible, tough luck. So far I just went with
Copy code
inline fun <reified T> Future<T>.asCompletableDeferred(): Deferred<T> =
    CompletableFuture.supplyAsync { this.get() }.asDeferred()
and it works, as far as I can see. But I’d like to omit unnecessary wrapping if
this
is already Completable:
Copy code
inline fun <reified T> Future<T>.asCompletableDeferred(): Deferred<T> =
    if (this is CompletionStage<*>) this.asDeferred() else CompletableFuture.supplyAsync { this.get() }.asDeferred()
and that is going all hysterical complaining that
this.asDeferred()
is no longer
Deferred<T>
but
Deferred<Any>
Why is that so and how to fix it?
e
because
<*>
j
oh nvm I see now that some class can be
MyFuture : Future<Int>, CompletionStage<String>
however stupid that seems…
e
exactly
j
and I can’t test
if (this is CompletionStage<T>)
because then “cannot check for erased type”
e
if you assume that nobody will do that, then go ahead and make a cast
you can do it further down
j
I think going
Copy code
inline fun <reified T> Future<T>.asCompletableDeferred(): Deferred<T> =
    if (this is CompletableFuture<T>) this.asDeferred() else CompletableFuture.supplyAsync { this.get() }.asDeferred()
is good enough…
basically my use-case is for Kafka’s producer
send()
which returns ancient
Future<RecordMetadata>
(I’m not sure if it is Completable, tho)