I’ve thought about this potential feature a lot lately. By the way, I am not aware of any language supporting this(*), so if you do know one, please let me know. I’d be interested to see how it is done.
Okay, so here’s the thing:
Imagine you have some type Foo
, and you don’t have access to that type. That may be because it is part of the StdLib or an external library, or you’re just not allowed to change that type for some reason. But that type Foo
could conceptually implement the interface Bar
, it’s just that it wasn’t done by whoever wrote Foo
. With the help of a little adapter code, you could make Foo
implement Bar
. Except you can’t, because that’s not a supported feature of the Kotlin programming language (or any other language I am aware of).
If it was a feature, it could look like this, for example:
[public] implement Foo : Bar {
override fun someFunctionFromBar(): Int {
// 'this' refers to an instance of Foo
}
// ...
}
I’m really not sure what the syntax should be here, but I think you get the point.
Now, why would this be useful? I got one example for you:
Imagine you want to write a library that provides a lot of common core ML algorithms (for example, a library for categorical encoding, for distance measures, for normalization or whatever). Now, the coolest thing would be if that library was completely framework-agnostic, meaning that you can just use it in combination with the DS/ML/DL framework of your choice. Now, those frameworks might all have their own classes to model “data records”. Maybe they’re wrapping around regular arrays, maybe they’re using some kind of ndarray implementation or something completely else. But all of their classes to model such data records are conceptually the same, although it is very unlikely that they will implement a common interface.
Let’s suppose there would be such an interface, though. Then, you could easily just use that interface as your access point in your library to implement all your algorithms. For example, you could implement distance measures only relying on that common interface (let’s call it DataRecord
):
fun euclidean(): (DataRecord, DataRecord) -> Double = { p, q ->
val dim = requireSameDimension(p, q)
var sum = 0.0
for (i in 0 until dim) {
sum += sqr(p[i] - q[i])
}
sqrt(sum)
}
Now we know that this convenient interface does not exist, so let’s just write our own, in which we expose any functionality a common data record should have. Now with the ability to implement interfaces for existing types, we could write little adapters for all major frameworks, and tell the users of the library that they can even write their own adapter if their framework of choice is not supported.
I think you get the point of this. There are a lot of other applications for this feature, so if you have an idea of another useful application, let me know.
So, what do you think? Should this be a language feature? Would you use it?
(*) - I don’t know enough about Rust to know whether impl Trait for Type
would actually work the way I describe this feature.