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.