Are polymorphic calls in Kotlin/Native static or d...
# kotlin-native
k
Are polymorphic calls in Kotlin/Native static or dynamic?
👀 1
d
Dynamic (Mostly). Monomorphisation is not performed and there's no JIT.
k
Gotcha. If monomorphisation isn't performed, how does K/N deal with generics? For method calls, why choose to perform polymorphism dynamically instead of statically?
Do you have any resources I can read to get a grip on how K/N works under the hood?
d
Ha! I wish such resource existed.
Generics are erased like on the JVM.
k
Ouch. Do you know why this design decision was made?
d
Compatibility with Kotlin/JVM
If they were to break compat, might as well build another Rust lol
k
Was it mainly just to stay aligned with the JVM? I know
reified
is a thing...but that could be a no-op in native
d
Yeah multiplatform would be incredibly difficult if they didn't align.
refied is a tricky one
k
There isn't direct compat between K/N and JVM, it's just implementation details of how language features are compiled, right?
Yeah multiplatform would be incredibly difficult if they didn't align.
Do you have any examples that highlight this?
d
Reified functions are inlined at compile time, you could almost call it monomorphisation.
😆 1
Don't have any examples of that sadly.
k
Womp. Thanks though!
d
Even the whole concurrency rules that are enforced at runtime already make multiplatform somewhat difficult.
k
Yeah, and I understand that's being worked on. I'm mainly asking this out of curiosity. I'm going to keep digging and see if I can get some answers
d
Polymorphism also can't be performed statically btw.
JVM can pull it off because it literally compiles the code at runtime.
k
Give me a second, because I have a precise example in my head and I want to know where it breaks down
👍🏼 1
d
Yeah best option now is to read source code and perhaps watch KotlinConf videos.
k
So I have an interface,
A
Copy code
interface A { fun foo() }
and it has two implementations,
B
and
C
Copy code
class B : A { override fun foo() = Unit }
class C : A { override fun foo() = println("") }
When making a call to an instance of B or C, the JVM will look into the Virtual method table to figure out which function to be invoked. I'm not quite sure why this is necessary, as this seems like it could be totally enforced by the compiler? I have very limited compiler knowledge, so please bare with me
Above, "the compiler" refers to konan
d
Ohh
You've kinda got a point there.
Konan will "perform it statically" in that case because polymorphism is not being used.
k
What if I said this
d
On the JVM all functions are overridable by default so it must check the vtable.
k
Copy code
val bar = listOf(C(), B())
bar.forEach { it.foo() }
that's certainly polymorphic
d
Yes definitely.
k
would that be able to be resolved by the compiler alone?
d
Hmm, tricky. A sufficiently advance compiler yes, but konan is not that haha.
k
Certainly not 😂
tis but a 👶
d
Indeed
k
Thanks for entertaining this lol. Looks like I've got some digging to do
d
Good talk. Have fun indulging in the compiler internals.
k
After looking around the K/N github, it seems like they answer questions tagged with
kotlin-native
on stackoverflow
After doing a bit of research on static dispatch (and rust) I've come to some partial conclusions. Consider the following function
Copy code
interface A
class B : A
class C : A

fun foo(a: A)
If the same method that rust employs were to be taken in Kotlin, then polymorphism is really shorthand for generic bounds. It could be transformed into the following
Copy code
fun <T : A> foo(a: T)
Using monomorphism, the compiler would search through all usages of this function to see what concrete types actually call this function. And then it would implement them for those classes.
Copy code
fun foo_b(a: B)
fun too_c(a: C)
Could this method be employed for class inheritance and not interfaces? I don't know. Rust doesn't allow inheritance and this might be the reason they can pull off total static dispatch. At the very least, it seems like Kotlin might be able to do it for interfaces.
d
Yes, I think it's being considered but for the far future.