Argument polymorphism

Suppose I have a hierarchy of types:

interface I

class A: I
class B: I
class C: I

If I want to implement code that is polymorphic wrt. the I hierarchy, but outside of it, right now this is the only solution I can see:

fun f(x: I) = when (x) {
    is A -> f(x)
    is B -> f(x)
    is C -> f(x)
    else -> error("Unsupported ${x.javaClass}")
}

private fun f(a: A) = TODO()
private fun f(b: B) = TODO()
private fun f(c: C) = TODO()

(The else branch is unneeded if the I hierarchy is sealed, but this is not the point I wish to make. Also the specialized f()s don’t need to be private, but it makes this exposition clearer.)

Is there any way to achieve polymorphism on the dynamic type of an argument in Kotlin?

For example, dynamically typed languages (like Groovy) would invoke the right f() according to the runtime type of argument x, without the need of a generic f() that performs an explicit selection. Kotlin does the same only for the receiver, and only if the method is not an extension method.

In other words, Kotlin seems to inherit from Java the virtual resolution of methods according to the runtime type of the receiver (invokevirtual), but apparently also the limitation on static resolution wrt. to the type of arguments. Wouldn’t this be relatively easy to implement with invokedynamic? Has this been considered at all?

Apparently dalewking answered this in '18: Multimethods, generic functions - #5 by dalewking

1 Like