Reputation: 14419
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 ?
Upvotes: 7
Views: 1755
Reputation: 33789
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.
Upvotes: 5