David Kubecka
10/21/2024, 2:46 PMfun test() = 1
fun test(x: Int = 1) = 1
fun main {
test() // which function is actually called?
}
Wouldn't it be more sensible (honoring the principle of least surprise) to actually throw an "ambiguous resolution" error?hho
10/21/2024, 3:08 PMAny non-parameterized callable is a more specific candidate than any parameterized callable
hho
10/21/2024, 3:15 PMfun test(x: Int = 1, y: String = "foo") = "bar"
fun test(x: Int = 1, y: Int = 2) = 3
fun main() {
println(test()) // compile error: Overload resolution ambiguity
}
David Kubecka
10/21/2024, 3:19 PMVampire
10/21/2024, 3:49 PMephemient
10/21/2024, 3:59 PMdmitriy.novozhilov
10/21/2024, 6:12 PMRob Elliot
10/22/2024, 8:06 AMfun test(x: Int = 1)
is syntax sugar for fun test(x: Int = 1) = 1; fun test() = test(1)
, and so I'd have been surprised that you could also define fun test()
separately.ephemient
10/22/2024, 8:15 AM@JvmOverloads
should indicate that it's not, IMO…David Kubecka
10/22/2024, 8:26 AMfun test(x: Int = 1) = 1
, so test()
returns 1. But if I now add fun test() = 2
suddenly my test()
code returns 2. Well, you could argue that's the principle of overloading and that's what we are used to in OOP but for top-level functions I find it quite surprising.ephemient
10/22/2024, 8:31 AMfun test(x: Any) = 1
and later add a
fun test(x: Int) = 2
which changes the resolution of existing codeRob Elliot
10/22/2024, 8:35 AM@JvmOverloads
should indicate that it's not, IMO…
I don't think knowing about the behaviour of platform specific annotations is immediately obvious, either - I do, because I've done a lot of gradual migrations from Java to Kotlin over the last 5 years and still have a load of Groovy tests that interact with Kotlin code, but anyone writing pure Kotlin could go a long time before encountering it.
I think it's more obvious that something more complicated than simple overloading is going on when you consider the case of multiple defaulted parameters with the same type - since Kotlin allows positional calling, fun test(x: Int = 1, y: Int = 2): Int = 1
cannot simply be syntax sugar for this:
fun test(x: Int, y: Int): Int = 1
fun test(x: Int): Int = test(x, 2)
fun test(y: Int): Int = test(1, y)
fun test(): Int = test(1, 2)
because the 2nd & 3rd evidently conflict when called with positional parameters.Rob Elliot
10/22/2024, 8:37 AMVampire
10/22/2024, 9:31 AMfun test(x: Any)
vs. fun test(x: Int)
. If you call test(1)
then it is not immediately obvious which one is used as both match. Documentation, experience, and gut feeling tell me it is the more specific Int
one. Just the same documentation, experience, and gut feeling tell me the one without parameter is preferred, as it directly matches what the user tried to call and needs less parameters defaulted.Vampire
10/22/2024, 9:32 AMDavid Kubecka
10/22/2024, 9:42 AMephemient
10/22/2024, 10:28 AM