gypsydave5
gypsydave5

Reputation: 582

Why does Kotlin have two syntaxes for lambdas / anonymous functions?

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?

Upvotes: 32

Views: 9032

Answers (1)

yole
yole

Reputation: 97338

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.

Upvotes: 43

Related Questions