The next logical step once we pass a function to another function is to calling it. In Java, one needs to know the type of the higher-order function. For example, to execute a Function , one needs to call apply() and pass a parameter with the expected type; to execute a Predicate , the function is called test() , etc.

Function < String , String > toLowerCase = String: : toLowerCase ; toLowerCase . apply ( "A" ); Predicate < String > isLowerCase = s -> s . equals ( s . toLowerCase ()); isLowerCase . test ( "A" );

Kotlin is more consistent, as there’s a single function called call() , defined on the KCallable interface.

fun isLowerCase ( string : String ) = string == string . toLowerCase () val callable : Boolean = :: isLowerCase . call ( "A" )

However, call() accepts any number of arguments of type Any? . It’s up to the caller to pass the correct number and type for parameters. The following compiles but will fail at runtime:

val callable : KCallable < String > = :: isLowerCase . call ( "A" , 2 , Any ())

To benefit from the compiler, one can use the KFunctionX type with X being the number of parameters that the function accepts. That type provides an invoke() function with the correct number of arguments and their types.

val ok : KFunction < String , Boolean > = :: isLowerCase . invoke ( "A" ) (1) val ko : KFunction < String , Boolean > = :: isLowerCase . invoke ( "A" , 2 , Any ()) (2)

1 Compiles 2 Doesn’t compile

Icing on the cake, invoke() is an operator function which operator is…​ nothing, so that the following syntax is also valid: