kotlinfunctional-programmingkotlin-higher-order-functions

Kotlin Higher-order functions


I am new in functional programming language and I just came through a new concept called Higher-order function.

I have seen Higher-order functions such as filter(), map(), flatMap(), take(), drop() and zip(). I have only seen these higher order functions in kotlin documentation.

My question is: These are the only these higher-order functions available in kotlin or there are more higher-order functions also available.

I am not sure, Can we also create higher-order functions for personal use or not?

Thanks in advance.


Solution

  • As mentioned in the Comparison to Java page's 4th point, Kotlin has proper function types, as opposed to Java's SAM-conversions.

    What I mean by that is if you want to accept a function or some sort of code in Java that you can call inside a function you need an external interface having exactly 1 method which is aware of the return type and the parameter signature.

    For example in Java:

    // You can't create this unless you create FuncInterface defining its parameter and return type
    MyFuncInterface a = (s) -> System.out.println(s);
    
    interface MyFuncInterface {
        public void myMethod(String s);
    }
    
    // now call a like
    a.myMethod("Hello World"); // will print: Hello World
    a.myMethod("Test");        // will print: Test
    

    While it is not the case in kotlin, you can create lambda without creating an interface here.

    For example same code in Kotlin could be converted into:

    val a: (String) -> Unit = { println(it) }
    // or like this: val a: (String) -> Unit = { s -> println(s) }
    
    // call like this
    a("Hello World") // will print: Hello World
    a("Test")        // will print: Test
    

    Since Kotlin has proper function types, you can make a function accept a function type or return one, which is then be called a Higher-Order Function.

    Concept is similar:

    // This is a higher order functon, takes a callable function `f`
    fun operatesFOn(num1: Int, num2: Int, f: (Int, Int) -> Int) {
        // this types are useful as callbacks, instead of taking nums and passing them
        // you can compute heavy tasks and when they complete call f with the result
        return f(num1, num2)
    }
    
    // lambda can be put outside the parentheses if it is last parameter
    // also is another higher order function which calls the lambda passed with the object it was called on as a parameter
    operatesFOn(3, 4) { a, b -> a + b }.also { println(it) } // prints: 7
    operatesFOn(5, 7) { a, b -> a * b }.also { println(it) } // prints: 35
    

    There are some other cool modifiers as well for higher order functions like the inline modifier.

    inline fun operatesFOn(num1: Int, num2: Int, f: (Int, Int) -> Int) {
        return f(num1, num2)
    }
    

    The above one will work similar but the lambda will instead be inlined at the call-site in compile time, to decrease the call-stack increasing the performance. as mentioned in the docs as well:

    Using higher-order functions imposes certain runtime penalties: each function is an object, and it captures a closure, i.e. those variables that are accessed in the body of the function. Memory allocations (both for function objects and classes) and virtual calls introduce runtime overhead.