Kotlin docs stated that it supports higher-order functions. Why would the language even need a ::function
syntax when passing a top level function as an argument?
Given:
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(::isOdd)) // here.
Why not just
fun isOdd(x: Int) = x % 2 != 0
val numbers = listOf(1, 2, 3)
println(numbers.filter(isOdd)) // simple and makes more sense
More on the function reference syntax here.
Kotlin supports the notion of first-class functions - functions can be saved to variables, passed into functions, and returned from functions. When you need to do this, you can create lambdas - function literals - or you can refer to an existing function by means of a function reference.
A function is a unit of code that performs a special task. In programming, function is used to break the code into smaller modules which makes the program more manageable. For example: If we have to compute sum of two numbers then define a fun sum().
I.e., the arguments to the function are passed by value and not by reference. Trying this in Kotlin, the compiler will help you out by saying that you can't reassign a val. So Kotlin declares the arguments to functions as values, equivalent to java finals.
Fact is that this notations can be used interchangeably, but it is better to use anonymous functions when we need to use return more then once. Lambda expression should be preferred for small functions with single expression. Although there are some cases when it is better to use anonymous function instead.
Kotlin language design tries to avoid ambiguous situations where some absence of something could be both correct and incorrect syntax at the same time. For example if you allowed the proposed syntax:
isOdd // error, function invocation expected isOdd(...)
isOdd // not error, you have a function reference
The ::
is a clear signal as to the intent. Because of this, you get only an error in the isOdd
case because you now have possibilities that do not overlap:
isOdd // error, function invocation expected isOdd(...)
::isOdd // function reference
isOdd() // error, missing parameter x
isOdd(x) // function call
This is why Kotlin avoids things that lead to ambiguous states. Your eyes can also quickly pick up the problem, just as the IDE and static analysis can, just as the compiler does. If you start allowing this looser syntax you will start running into compounded ambiguities such as when using as infix functions and so on. Language design is more complicated than "oh, let's make them type less characters" because the complexity matrix is much larger than you imagine if you only look at one use case ignoring all the others.
Because Java (and, therefore, Kotlin) uses separate namespaces for fields and methods, you need ::
to avoid ambiguities. Example:
val isOdd : (Int) -> Boolean = { x -> x % 2 != 0 }
fun isOdd(x: Int): Boolean {
return x % 2 != 0
}
val odds = listOf(1,2,3).filter(isOdd) // uses the val version
val otherOdds = listOf(1,2,3).filter(::isOdd) // uses the fun version
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