[Resolved] Kotlin Overload and Bound Callable Reference Syntax Issues

Hi all,

I’ve been working my way through Baeldung’s reactor-core tutorial and attempting to translate the examples to Kotlin. I’ve run into a few issues I could use some help understanding/figuring out.

First Example

Java:

List<Integer> elements = new ArrayList<>();
 
Flux.just(1, 2, 3, 4)
  .log()
  .subscribe(elements::add);

Kotlin:

val elements = mutableListOf<Int>()
Flux.just(1, 2, 3, 4)
    .log()
    .subscribe(elements::add)

Using elements::add should be possible thanks to 1.1’s bound callable references, but I’m getting this error:

This works though:

.subscribe({ elements.add(it) })

Any idea why?

Second Example Fixed, Solution At Bottom

Java:

Flux.just(1, 2, 3, 4)
  .log()
  .map(i -> i * 2)
  .zipWith(Flux.range(0, Integer.MAX_VALUE), 
    (two, one) -> String.format("First Flux: %d, Second Flux: %d", one, two))
  .subscribe(elements::add);

Kotlin:

Flux.just(1, 2, 3, 4)
        .log()
        .map({ i -> i * 2})
        .zipWith(
                Flux.range(1, Int.MAX_VALUE),
                { two: Int, one: Int ->
                    Flux.just("First Flux: $one, Second Flux: $two")
                }
        )
        .subscribe({ elements.add(it) })

This gives an error on zipWith:

I tried using an anonymous function with a return type, but that didn’t work either. I’m not sure how to decipher what this error means. I assume the lambda doesn’t translate to a BiFunction, but I’m not sure how to fix that.

I was able to get this working by using the following:

.zipWith<Int, String>(
  Flux.range(1, Int.MAX_VALUE),
  BiFunction {
    two, one ->
    "First Flux: $one, Second Flux: $two"
  }
)

Kotlin was unable to determine which Java method overload I was attempting to use.

Any help would be greatly appreciated!

1 Like

This is a known issue that we hope is going to be fixed with the new resolution & inference algorithm planned for Kotlin 1.2: https://youtrack.jetbrains.com/issue/KT-11723

1 Like

Good to know! Thank you @udalov

I don’t know whether it is part of the plan, but it would be nice if the algorithm would be able to choose between a base class and subclass extension receiver (and use the more specialised version). This is for an update builder that the extension wraps into a transaction. The receivers are both interfaces and the function must be inline so the only solution is an extension function.