I always wondered why sometimes with function literals we can ignore the curly brace even for multiple statements. To illustrate this, the syntax for a multiline function literal is to enclose the statements with curly braces. Like so,
val fl = (x: Int) => {
println("Add 25 to "+x)
x + 25
}
However, when you pass it to a single-argument function, you can ignore the required curly brace for the function literal.
So for a given function f,
def f( fl: Int => Int ) {
println("Result is "+ fl(5))
}
You can call f() like this,
f( x=> {
println("Add 25 to "+x)
x + 25
})
-------------------------
Add 25 to 5
Result: 30
Or when you use curly braces instead of parenthesis in the function call, you can remove the inner curly braces from the function literal. So the following code will also work,
f{ x=>
println("Add 25 to "+x)
x + 25
}
The above code is more readable and I notice that a lot of examples use this syntax. However, is there any special rule that I may have missed, to explain why this is working as intended?
There are just a couple of simple syntax rules. The appendix of the spec is worth perusing.
A function literal or anonymous function (6.23) will look like
x => Expr
orx => Block
depending on whether the context is an Expr or a ResultExpr, respectively.A function application (6.6) will look like
f(Expr, Expr)
orf BlockExpr
, i.e.,f{ Block }
. That is, a BlockExpr is just a sequence of block statements inside{...}
.When you call
f(g)
, then g is an Expr, so as a function literal,x => Expr
. The Expr can be a BlockExpr,x => { ... }
.When you call
f{ Block }
, thenf { x => ... }
has the function literal in ResultExpr of a Block (which is just a sequence of statements, no braces required).Here, it's obvious that the anon func is at the bottom of a block: