https://kotlinlang.org logo
Title
e

elect

03/27/2019, 4:18 PM
why
@JvmName
cant do anything here?
@JvmName("getI") fun get(): Int = 0
    @JvmName("getF") fun get(): Float = 0f // error, signature clash
d

diesieben07

03/27/2019, 4:19 PM
The problem is not a platform declaration name clash. The JVM could handle this just fine (the whole signature including parameters and return type counts). This is a "limitation" (if you want to call it that) of the Kotlin language itself. You cannot overload based on return type, only parameter types.
1
How would you imagine the following to work?
val foo = get()
What would the type of
foo
be? Which version of
get
would be called?
e

elect

03/27/2019, 4:20 PM
plain easy: like when the type parameter can be avoided, in this case the variable type must be explicitely declared
d

diesieben07

03/27/2019, 4:21 PM
That is not possible in Kotlin. It's simply not how the type inference engine works
e

elect

03/27/2019, 4:22 PM
might Contracts be useful here?
d

diesieben07

03/27/2019, 4:23 PM
Kotlin favors being explicit in favor of being overly concise. What you propose just causes too many edge cases. What if I do this:
foo(get())
- Now the parameter type of
foo
decides which version of
get
I call. If at some point someone changes
foo
from accepting just
Float
and adds an overload for
Int
you now suddenly have an incompatible change.
Just one example of the problems this causes.
e

elect

03/27/2019, 4:24 PM
I really dont get why it's so difficult
d

diesieben07

03/27/2019, 4:24 PM
It's not difficult. It is just not a good idea.
e

elect

03/27/2019, 4:25 PM
if we have the compiler warning us to explicitely override a method when a class has two extensions with the same method, would this be so different?
d

diesieben07

03/27/2019, 4:26 PM
I am not sure what kind of warning you are referring to
If you take my example above,
foo
and
get
can be in completely separate libraries. There is no way for the compiler to see this while writing
foo
or
get
, since they are not developed together.
e

elect

03/27/2019, 4:27 PM
interface A {
    fun foo() = 0
}
interface B {
    fun foo() = 2
}
class C : A, B  // C must implement foo
d

diesieben07

03/27/2019, 4:28 PM
I am not sure how that is in any way related.
e

elect

03/27/2019, 4:28 PM
it's an edge case
in your previous case, the compiler should simply prohibits cases with ambiguity
d

diesieben07

03/27/2019, 4:30 PM
Exactly. But the ambiguity could be introduced by a third party simply introducing a 2nd overload. Which is not expected.
e

elect

03/27/2019, 4:31 PM
if you have just
foo(Float)
is fine, but if you have also
foo(Int)
, then there is ambiguity. The compiler shall be told somehow which one use by the dev.
Ambiguity gone, like when
C
implements
foo
anyway, I dont want to rantle any longer. I'd need something quickly
atm, it looks like to overcome the signature clash there are only two ways: - change signature - use reified
any other?
r

robstoll

03/27/2019, 4:51 PM
You could use a dummy type parameter as distinction
e

elect

03/27/2019, 4:52 PM
thanks, but I'd still prefer modify the method name in that case
I also found out passing
<A>
may give some space
but you cant overload further though..
l

louiscad

03/27/2019, 6:14 PM
What are you actually getting there? Maybe we can help for naming.
1
e

elect

03/28/2019, 8:11 AM
basically a wrapper for opengl, there are many tens of functions like this one, https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGet.xhtml, where you have to query a parameter and the only difference is the return type
this is my biggest use case class though, @louiscad: https://github.com/kotlin-graphics/gln/blob/master/src/main/kotlin/gln/gl.kt