I can write a lambda expression outside of parenthesis, but I cannot put it there by name. I have tried many ways:
val plus3: (Int,Int,Int)->Int = {a,b,c->a+b+c}
println(apply3(1,2,3){a,b,c->a+b+c}) // OK
println(apply3(1,2,3){plus3}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int
println(apply3(1,2,3){(plus3)}) // Type mismatch. Required: Int, Found: (Int,Int,Int)->Int
println(apply3(1,2,3)plus3) // unresolved reference
println(apply3(1,2,3){plus3()}) // value captured in a closure
println(apply3(1,2,3){(plus3)()}) // value captured in a closure
What is the syntax to put a name there (outside of parenthesis)?
I don't know why, but in the documentation there is not a word on the theme. It says we could put lambda there, but not a word about a variable or constant that denotes that lambda.
I don't know why, but in the documentation there is not a word on the theme.
Yes, there is:
In Kotlin, there is a convention that if the last parameter to a function is a function, and you're passing a lambda expression as the corresponding argument, you can specify it outside of parentheses
plus3
is an identifier and not a lambda expression, so you can't specify it outside of parentheses.
The type of plus3 is (Int,Int,Int->Int). The same as of {a,b,c->a+b+c}. Look again at the messages that I am getting from Kotlin compiler.
You mean the error messages when you pass { plus3 }
? By Kotlin rules { plus3 }
is a lambda which ignores its argument (if any) and returns plus3
. So the rule applies, and apply3(1,2,3){plus3}
means the same as apply3(1,2,3,{plus3})
.
It sees plus3 as Int.
Exactly the opposite: it expects to see an Int
as the return value of the lambda and sees plus3
which is (Int,Int,Int) -> Int
.
So, the problem here is not of the high philosophical nature, but seems pure syntactic.
That was exactly my point: the rule is purely syntactic, it's applied before the compiler knows anything about type or value of plus3
, and so it doesn't know or care whether this value happens to be a lambda.
The rule could instead say
In Kotlin, there is a convention that if the last parameter to a function has a function type, you can specify it outside of parentheses
in which case apply3(1,2,3) plus3
would work. But it doesn't.
Placing a lambda expression outside of a function call's parentheses is the same as placing it inside the parentheses like this:
println(apply3(1, 2, 3, { a, b, c -> a + b + c }))
From here, we can simply assign the lambda to a val
(as you have done) which results in:
val plus3: (Int, Int, Int) -> Int = { a, b, c -> a + b + c }
println(apply3(1, 2, 3, plus3))