Hello, World! I made an extension fun on a type t...
# announcements
b
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
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
All right. But why?
and why is this allowed?
k
Both good questions.
😂 1
r
Well that’s obvious, the source always has priority over extensions, because they’re just that, extensions.
m
no, not obvious. And you could argue the same for overriding functions 😄 Extensions could basically be seen as quite similar, just static instead.
r
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
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
Maybe there should be a shadow warning for this
d
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
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
@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
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
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
I have a good idea of how extensions are implemented on the JVM, and again, I find nothing obvious about that design choice.
m
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