45

It seems that the last line of a lambda always returns that value even if you omit the return statement. Is this correct? Is it documented anywhere?

fun main(args: Array<String>) {
    val nums = arrayOf(1, 2, 3)
    val numsPlusOne = nums.map { it -> 
        val r = it + 1
        r
    }
    // numsPlusOne = [2, 3, 4]
}
1
  • 6
    Just a helpful hint, you can shorten that to val numsPlusOne = nums.map { it + 1 } (because it is implied if not specified, and if it + 1 is the last line, its result will be returned as @hotkey explained) Commented Jan 12, 2017 at 20:52

1 Answer 1

61

Yes, this is correct, if the last statement of a lambda is an expression, it is considered its return value.

Here's what the reference says (thanks @KirillRakhman):

We can explicitly return a value from the lambda using the qualified return syntax. Otherwise, the value of the last expression is implictly returned. Therefore, the two following snippets are equivalent:

ints.filter {
    val shouldFilter = it > 0 
    shouldFilter
}

ints.filter {
    val shouldFilter = it > 0 
    return@filter shouldFilter
}

The last statement semantics is also true for if (that's why there's no ternary operator), when and try-catch blocks, and these statements are expressions themselves:

val foo = if (bar) { 
    doSomething()
    baz 
} else { 
    doSomethingElse()
    qux 
}

See also: examples for when and try-catch.

So, lambdas are consistent with the language constructs in this respect.


If you want to make an explicit return statement in a lambda, use the return@label syntax (also, another answer with examples). Non-labeled return, on contrary, works with the nearest fun (ignoring lambdas) and thus can only occur in those lambdas which are inlined.

There was a language proposal to add special syntax for emitting a value from a code block, but it was rejected.

Sign up to request clarification or add additional context in comments.

3 Comments

"if the last statement of a lambda is an expression" - I can't find a definitive source for definitions, but I think it's incorrect to call the "expression" a "statement". The Kotlin docs only say "the value of the last expression is implicitly returned". My understanding is that statements typically don't produce values and that an expression is not a type of statement
@mowwwalker Well, while this is arguable, in the Kotlin grammar, one kind of a statement is an expression, which may be a dangling unused value or a function call whose return value is ignored.
Ah awesome that settles that then :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.