# Why the method I need was not called?

**URL:** <https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126>\
**Category:** Uncategorized\
**Created:** [June 17, 2020, 5:59pm UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126 "2020-06-17T17:59:33Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![OptimumOpium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/optimumopium/32/7681_2.png) [@OptimumOpium](https://discuss.kotlinlang.org/u/OptimumOpium)\
**Post date:** [June 17, 2020, 5:59pm UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126/1 "2020-06-17T17:59:33Z")

</div>

Could you please explain why the method I need was not chosen in the following cases?

> **Versions used**
>
> Java: 1.8.0\_251 Oracle (also checked on 11.0.5 AdoptOpenJDK HotSpot)  
> IDE: IntelliJ IDEA 2020.1.2 (Community Edition) Build #IC-201.7846.76, built on June 1, 2020  
> Kotlin plugin: 1.3.72-release-IJ2020.1-5

1. The case where everything works fine

```kotlin
import java.math.BigDecimal

fun main() {
    printAny(5.0.toBigDecimal())
    printAny(listOf(5,6,7))
    printAny(1.2)
}

fun printAny(obj: Any) {
    println(obj.toPrintable())
}

fun BigDecimal.toPrintable(): String {
    return toPlainString()
}

// case 1 - normal
fun Iterable<*>.toPrintable(): String {
    return joinToString(",")
}

fun Any.toPrintable(): String {
    return when(this) {
        is BigDecimal -> toPrintable()
        is Iterable<*> -> toPrintable()
        else -> "(default)" + toString()
    }
}

```

> **Result**
>
> 5.0  
> 5,6,7  
> (default)1.2

1. Use generic type in `Iterable.toPrintable()` (please, don’t ask why 🙂)

```kotlin
fun <T> Iterable<T>.toPrintable(): String {
    return joinToString(",")
}

```

As a result, we will get StackOverflowError because the method will not be used and we will call `Any.toPrintable()` again and again.

1. Use generic again but for `Iterable` we will use a wildcard.

```kotlin
fun <T> Iterable<*>.toPrintable(): String {
    return joinToString(",")
}

```

And again we will get StackOverflowError.

**P.S.** In all cases, the IDE displayed correctly whether the method is used or isn’t. However, when I used the previous version of the Kotlin plugin (unfortunately, I didn’t check the version before updating) the IDE showed that methods are used in the 2nd and the 3rd cases.

**P.P.S** If we check generated classes we will see that in the first case a cast to Iterable will be used  
`$this$toPrintable instanceof Iterable ? toPrintable((Iterable)$this$toPrintable)`  
When in other cases it won’t  
`$this$toPrintable instanceof Iterable ? toPrintable($this$toPrintable)`

**P.P.P.S.** The test project is attached.  
[test-kt-bug.zip](https://discuss.kotlinlang.org/uploads/short-url/id04X80TrV4HQfH2C5yPaHUTfAS.zip) (58.4 KB)

---

<div class="post-metadata">

**Author:** ![arocnies](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/arocnies/32/5143_2.png) [@arocnies](https://discuss.kotlinlang.org/u/arocnies)\
**Post date:** [June 17, 2020, 7:26pm UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126/2 "2020-06-17T19:26:07Z")

</div>

Just thought I’d add a runnable example. I recommend the runnable examples because you can edit it to try modifications right from the forum. I left in the whole example so it’s editable not just a sample.

Try adding `<T>` (which is case 3) to the function below.

```run-kotlin
import java.math.BigDecimal

fun main() {
    printAny(5.0.toBigDecimal())
    printAny(listOf(5,6,7))
    printAny(1.2)
}

fun printAny(obj: Any) {
    println(obj.toPrintable())
}

fun BigDecimal.toPrintable(): String {
    return toPlainString()
}

// case 1 - As shown
// case 2 - Change to "fun <T> Iterable<T>.toPrintable(): String"
// case 3 - Change to "fun <T> Iterable<*>.toPrintable(): String"
fun Iterable<*>.toPrintable(): String {
    return joinToString(",")
}

fun Any.toPrintable(): String {
    return when(this) {
        is BigDecimal -> toPrintable()
        is Iterable<*> -> toPrintable()
        else -> "(default)" + toString()
    }
}

```

---

<div class="post-metadata">

**Author:** ![nickallendev](https://avatars.discourse-cdn.com/v4/letter/n/cdc98d/32.png) [@nickallendev](https://discuss.kotlinlang.org/u/nickallendev)\
**Post date:** [June 18, 2020, 2:51am UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126/3 "2020-06-18T02:51:38Z")

</div>

Sounds like the intended behavior specified in the [Spec](https://kotlin.github.io/kotlin-spec/#choosing-the-most-specific-candidate-from-the-overload-candidate-set)

> Any non-parameterized callable (which does not have type parameters in its declaration) is a more specific candidate than any parameterized callable

---

<div class="post-metadata">

**Author:** ![OptimumOpium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/optimumopium/32/7681_2.png) [@OptimumOpium](https://discuss.kotlinlang.org/u/OptimumOpium)\
**Post date:** [June 18, 2020, 8:58am UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126/4 "2020-06-18T08:58:52Z")

</div>

Thanks for the reference to the spec.

If I read it correctly the presence of any type parameter in a function declaration (even if it is not used) makes the function less specific than a function that doesn’t have any type parameter in the declaration at all.

Please, correct me if I didn’t get it right.

---

<div class="post-metadata">

**Author:** ![OptimumOpium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/optimumopium/32/7681_2.png) [@OptimumOpium](https://discuss.kotlinlang.org/u/OptimumOpium)\
**Post date:** [June 18, 2020, 9:23am UTC](https://discuss.kotlinlang.org/t/why-the-method-i-need-was-not-called/18126/5 "2020-06-18T09:23:12Z")

</div>

I did a small example to check it. And I guess the reason why the function wasn’t chosen is that there wasn’t enough information to infer the type. So the compiler chose another function.

```run-kotlin
fun main() {
    printAny("")
    printAny(listOf<Any>())
    printAny(2)
}

fun printAny(obj: Any) {
    when (obj) {
        is String -> obj.doSomething()
        is Iterable<*> -> obj.doSomething()
        else -> obj.doSomething()
    }
}

// If you add the type parameter here
// you will get a compilation error on line
// is String -> obj.doSomething()
fun /*<T>*/ String.doSomething() {
    println("String")
}

fun Iterable<*>.doSomething() {
    println("Iterable")
}

fun Any.doSomething() {
    when (this) {
        // but you won't get an error here
        // the method for Any will be chosen instead
        is String -> doSomething()
        is Iterable<*> -> doSomething()
        else -> println("default")
    }
}

```
