Functional interface invoke


#1

Maybe it’s an idea to add invoke-functions to functional-interfaces?
The way it should act is like generated extension-functons.


#2

I think there is some undocumented magic going on with function types or at least I can’t find the right documentation.

fun foo() {}
val a = ::foo // a is of type KFunction0<Unit>

The strange thing is that based on the documentation I can find, there is no class KFunction0. Also Intellij does not let me jump to it’s declaration. I guess it has something to do with the special function type syntax () -> Unit. The only somewhat related class I could find is Function0<T> but this only exists on the JVM and I have no idea what it is used for.

fun foo() {}
val a: KFunction0<Unit> = ::foo   // valid although KFunction0 does not seem to exist
val b: Function0<Unit> = ::foo    // valid as well, I guess KFunction0 extends Function0 which declares `invoke`
val c: () -> Unit = ::foo         // as far as I can tell this is a special syntax for KFunction0

Another strange fact is that looking at the docs for Kotlin 1.3 they have KFunction0, etc but only for Kotlin native? The native version of KFunction0 does not have the invoke operator though.
So I guess what I’m trying to say is that the documentation of how this works is lacking in multiple regards.

Anyways, why exactly do you need the functional-interfaces to have invoke declared? I mean you can still call it regardless.


#3

The reason I wanted to have the invoke-function with functional interfaces is because that is the way java defines lambda’s and lambda’s should be invokable, or is that to bluntly?


#4

Which functional interfaces exactly are you talking about. The way I understand it () -> Unit or any other functional interface is represented by some synthetic class KFunction0<T> which implements Function0<T> which declares invoke.
So I guess the functional interfaces have invoke already.

Maybe you can give an example of what you are trying to do (I’m not sure if I understand your problem yet).
As far as I know there should be no problem combining kotlin lambdas with java and vice versa.


#5

I put the link in because of your comments about the functions.
I was talking about java’s interfaces, annotated with @FunctionalInterface


#6

Ok, now I get you I think. For everyone else here is a link to the interface :wink:

So you want to be able to do something like this

// java
interface Foo extends FunctionalInterface {
    void foo();
}

// Kotlin
val foo: Foo = getFooFromJava() 
foo()

I agree this should be possible. Another solution to the problem would be something like this is reinterpreting Foo as () -> Unit in a similar way that kotlin maps other java types to their corresponding kotlin types. I think I prefer this as it would limit the number of functional interfaces we have to deal with in Kotlin.
That way you would have

val foo: () -> Unit = getFooFromJava()