Where does invoke for functions come from? Found no documentation on this

Given a function declaration named funcName, ::funcName returns an instance of type KFunction, which is a subtype of KCallable and Function. I browsed through the documentation of these interfaces and did not find an invoke method; I expected it to be part of Function. Obviously, (::funcName).invoke(...) and funcName.invoke(...) works and exists.

My best guess is that call of KCallable delegates the call to invoke of an otherwise inaccessible instance of Function. Is that correct? Why is there no invoke method declared anywhere (or where is it declared)?

invoke is part of Function0, Function1, etc. My guess is that it’s not part of function because invoke needs to know the types of the parameters/return type so it can’t be part of Function which doesn’t have this information.
How the actuall mapping between those interfaces works I’m not sure about. I think there is some compiler magic that somehow combines them.

1 Like

Thank you very much Burkhard! :+1: I missed looking up Function0 and friends. You are right, thanks!

In the github source, I just saw that there is only up to Function22.
Does this mean that if we try to declare and use a function which takes more than 22 parameters, it wouldn’t compile?

No worries :wink: There is FunctionN.kt for that, see link.

Oh, but why would we then need sth other than FunctionN if FunctionN can generalize everything?
And is there a reason people chose number of parameters N >= 23 as the border line?

FunctionN is most likely less efficient than the special versions… Having to create at least one additional array object.

I have no idea how 23 was chosen as the border.

If I remember correctly, the implementation just mirrors the way the Java implementation has done it. That doesn’t answer the question, why 23 is the magic number, but might be a pointer where to look for an answer.

My guess is that it is a somewhat random number. 22 is high enough that 99.9% of all lambdas should be covered by it but also not so insane that it creates a noticeable increase in file size for the library.
My guess is that they looked at functions with lot’s of parameters and just added a few just to be safe.
I found this article here: https://www.exakat.io/how-many-parameters-is-too-many/
It contains a nice graph of showing how often a function with n parameters exists at least once per project. The data is about php and I’m sure this is going to be different for java or kotlin but I think based on the graph somewhere around 20 seems like a reasonable number.