I put together a dummy problem to illustrate my point: Say that we have the following handy function to display information about a particular sorting algorithm:
fun sort(name: String, array: Array<Int>, sortingAlgorithm: (Array<Int>) -> Array<Int>) {
println(name)
sortingAlgorithm(array).forEach { print(" $it ") }
println()
}
You would use it like this:
sort("Selection Sort - Θ(n^2)", arrayOf(2, 3, 1), ::selectionSort)
And this works because the signature of selectionSort
is simple: fun selectionSort(array: Array<Int>): Array<Int> {
But say I have another sorting algorithm with the following signature
fun quickSort(array: Array<Int>,
start: Int = 0,
end: Int = array.size - 1): Array<Int> {
The last two arguments are optional, so in theory you could call quickSort
the same way you call selectionSort
. That is to say, it stil respects the signature (Array<Int>) -> Array<Int>
Right?
Unfortunately when I try to call sort("Quick Sort", arrayOf(2, 3, 1), ::quickSort)
I get:
I think that the compiler isn't being smart enough to realise that those two arguments are optional. How can avoid this problem, other than overloading the sort
method to accept a high order function with the signature ?
A higher order function is a function that takes a function as an argument, or returns a function .
Functions with optional arguments offer more flexibility in how you can use them. You can call the function with or without the argument, and if there is no argument in the function call, then a default value is used.
- A higher-order function accepts one or more functions as input and returns a new function. Sometimes it is required to use function as data. - To make high order function , we need to import functools module.
In a nutshell, a Higher-order function is a function that may receive a function as an argument and can even return a function. Higher-order functions are just like regular functions with an added ability of receiving and returning other functions are arguments and output.
There is no avoiding this problem since it would contradict 2 corner stones of Kotlin type system:
For example if you could do that, the following would not to work, which is a simple refactoring of your example:
val algorithm = ::quickSort
sort("Quick Sort", arrayOf(2, 3, 1), algorithm)
Anyways, the sort("Quick Sort", { quickSort(unsorted) })
workaround is too simple for Kotlin developers to spend spend time on the problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With