frankelot
frankelot

Reputation: 14419

Is it possible to use High order functions with optional arguments

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:

type missmatch

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

Answers (1)

voddan
voddan

Reputation: 33789

There is no avoiding this problem since it would contradict 2 corner stones of Kotlin type system:

  • 1) Every expression has a type (strong typing)
  • 2) The receiver side does not affect an expression's type (local inference)

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

Related Questions