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.
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.