Search code examples
functionkotlinlambdasyntaxanonymous-function

How does one bind a method to a name in Kotlin?


In Kotlin, the code snippet val f = println() binds the function println (which is a first class object) to the name f.

How do I do the same with the method map, i.e. store it in f?

The syntax val f = map does not work, neither does val f = arrayOf(1,2,3).map. I have tried various variations of the above, with no success.

Also (and related), why does val f = println not work, making the brackets necessary? I come from the functional programming camp (Scheme), where this would be absolutely normal.

(Disclaimer: absolute Kotlin novice, trying to learn it by myself.)


Solution

  • In Kotlin, the code snippet val f = println() binds the function println (which is a first class object) to the name f.

    Not true. This assigns the return value result of calling println(), which is Unit, to the variable f. To get a function reference, use ::. But you must also specify the variable type, because it cannot be inferred when the function has overloads:

    val f: (Any)->Unit = ::println
    

    A function with a receiver should be specified using the receiving type, like

    val f = Any::toString
    
    // or, to bind a specific instance's toString:
    val myList = listOf("Hello", "World")
    val myListToString = myList::toString
    

    Since map is a higher-order function, it has a long and complicated signature:

    val f: Array<Int>.((Int)->String)->List<String> = Array<Int>::map