https://kotlinlang.org logo
#announcements
Title
# announcements
b

bod

07/05/2019, 12:13 PM
Hello, World! I made an extension fun on a type that belongs to the Android sdk, and in a more recent version of this sdk they added a method to this type, with the same signature as my extension. To my surprise, in that case, the extension is ignored (the type's method wins). Thoughts?
k

karelpeeters

07/05/2019, 12:17 PM
It's in the docs: https://kotlinlang.org/docs/reference/extensions.html#extensions-are-resolved-statically
If a class has a member function, and an extension function is defined which has the same receiver type, the same name is applicable to given arguments, the member always wins.
(emphasis not mine)
b

bod

07/05/2019, 12:19 PM
All right. But why?
and why is this allowed?
k

karelpeeters

07/05/2019, 12:21 PM
Both good questions.
😂 1
r

ribesg

07/05/2019, 12:48 PM
Well that’s obvious, the source always has priority over extensions, because they’re just that, extensions.
m

Marc Knaup

07/05/2019, 12:58 PM
no, not obvious. And you could argue the same for overriding functions 😄 Extensions could basically be seen as quite similar, just static instead.
r

ribesg

07/05/2019, 1:04 PM
It’s obvious to me that an external static function that could be (and in this case, is) defined in an entirely different project doesn’t override a simple member.
d

Dias

07/05/2019, 1:05 PM
it's obvious in a sense of priority, but I guess the confusion is about compiler not giving errors, but just silently using member function
r

ribesg

07/05/2019, 1:05 PM
Maybe there should be a shadow warning for this
d

Dias

07/05/2019, 1:06 PM
like in this case you update a random dependency and all of a sudden your app is broken, and you don't even know about it
b

bod

07/05/2019, 1:30 PM
I really don't see what is obvious about that. You write an extension on a class, and import it, which means you want to use it. But it doesn't do anything.
in which case is this behavior desirable?
k

karelpeeters

07/05/2019, 1:33 PM
@ribesg It could also be an extension function defined in the current file and the other class could be defined far off, I don't see why there's an inherent sense of priority here.
b

bod

07/05/2019, 1:34 PM
I think we can all agree that at the very least, it should not be possible (compilation error) to do this?
👍 1
but even so, I believe it would be better if it was possible and worked as expected
r

ribesg

07/05/2019, 1:36 PM
Well maybe it’s more obvious for people who have been using Kotlin from the start, but think about how Kotlin extensions actually work on the JVM. Think about how it looks from Java code. When you have that floating somewhere in your head it’s obvious. If it’s not obvious to you then you should read more about what extensions actually are. That being said, I think that we could at least prevent defining extensions that can actually never be used, but you can always have a subclass defining a new member clashing with an extension of the superclass, and right there things start to become trickier
This compiles but triggers a warning, maybe this warning should be a compilation error:
Copy code
interface A {
    fun a()
}

fun A.a() {}
b

bod

07/05/2019, 1:39 PM
I have a good idea of how extensions are implemented on the JVM, and again, I find nothing obvious about that design choice.
m

Marc Knaup

07/05/2019, 1:39 PM
There are so many situations where subclassing is not option. And we shouldn't look too close at Java and JVM. Kotlin is its own language and slowly moving towards other platforms too. Fun thing is that such extensions unusable in Kotlin are actually usable in Java
2
2 Views