There are just a couple of simple rules.
A function that takes a single parameter f(x)
can take a block expression f { x }
.
The spec says just that:
If only a single argument is supplied, it may be supplied as a block expression and parentheses can be omitted, in the form f { block }
. This is valid when f
has a single formal parameter or when all other formal parameters have default values.
The second part is a bit obscure to me: You can use a block if you’re supplying a single arg.
An example where other args are implicit is Future { body }
.
An example where other args are default args is a test API in scala.tools.testkit
assertThrows(body, checkMessage = checker)
which can be invoked with the default checkMessage
:
assertThrows { ??? }
What is a block? It’s either some statements and a result expression, or a block of case clauses.
The spec links to the explanation of case clauses as a pattern-matching anonymous function.
List(42).collect { case i if i < 27 => i * 2 }
You get a function or a partial function, depending on the context.
For a regular block, such as
List(42).map { val x = 2 ; i => i * x }
the function literal is the result expression of the block. The code to the right of the arrow can be a sequence of block statements
List(42).map { val x = 2 ; i => val y = 3 ; i * x * y }
No extra braces are required around the body of the lambda (because the big block is already wrapped in braces, if you like).
It looks a little less naked when the block has only the result expression and begins with the formal parameter of the lambda:
List(42).map { i => val x = 2 ; val y = 3 ; i * x * y }
And it also looks more normal when written vertically.
Syntactically, it’s not weirder that the RHS of a lambda in a block result is a block, than that the RHS of a lamba expression is an expression (which may be a lambda):
(i: Int) => (j: Int) => i+j
It’s not terrible to write
List(42).map(i => { val x = 2 ; val y = 3 ; i * x * y })
as is necessary in a multiarg application
assertThrows(body, msg => { val n = msg.length ; n > 3 })