Kotlin has two ways of declaring an anonymous function (aka a lambda). The two different syntaxes are:
val lambda = { input : String ->
"received ${input}"
}
and
val anonymousFunction = fun (input : String): String {
return "received ${input}"
}
I understand the difference between the two (as outlined in this answer), but what I don't understand is why the language has two different ways of declaring the same thing.
Are there optimizations at work under the hood for one verses the other? Was the anonymous function version thought to be too verbose? Could the lambda version of the syntax not support a return type?
The anonymous function syntax allows you to specify the receiver type of a function literal directly. This can be useful if you need to declare a variable of a function type with receiver, and then to use it later.
Lambda expression is a simplified representation of a function. It can be passed as a parameter, stored in a variable or even returned as a value. Note: If you are new to Android app development or just getting started, you should get a head start from Kotlin for Android: An Introduction.
In Kotlin, we can have functions as expressions by creating lambdas. Lambdas are function literals that is, they are not declared as they are expressions and can be passed as parameters. However, we cannot declare return types in lambdas.
In Python, an anonymous function is a function that is defined without a name. While normal functions are defined using the def keyword in Python, anonymous functions are defined using the lambda keyword. Hence, anonymous functions are also called lambda functions.
The key reason is the support for returns from lambdas. The rule for returns is that the return
keyword returns from the nearest function declared with the fun
keyword. In some scenarios, you want a return
in a block of code to return from the enclosing function, so you use a lambda:
fun processElements(list: List<Element>): Boolean { list.forEach { element -> if (!element.process()) return false // returns from processElements() } return true }
In other scenarios, you want to return from the block but not from the enclosing function. When using a lambda, returning from the block requires the return@label
syntax, which is somewhat clunky:
fun processElements(list: List<Element>) { list.forEach { element -> if (!needToProcessElement(element)) return@forEach // returns from block element.process() } }
To avoid the clunkiness, we've provided an alternative syntax - anonymous functions - which allows you to use return
directly to return from the block:
fun processElements(list: List<Element>) { list.forEach(fun(element) { if (!needToProcessElement(element)) return // returns from block element.process() }) }
A secondary reason is that it's indeed impossible to fit the return type declaration into the syntax of a lambda, but this is very rarely needed in practice, so it's not particularly important.
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