Here is Scala code
#1
def method1 = {
map1.foreach({
case(key, value) => { println("key " + key + " value " + value) }
})
}
#2
def method1 = {
map1.foreach{
case(key, value) => { println("key " + key + " value " + value) }
}
}
It almost figures for me, but nevertheless I want to make it clearer: why is it possible to omit parenthesis in this case?
You can always exchange methods argument parentheses for curly braces in Scala. For example
def test(i: Int) {}
test { 3 }
The base for this is the definition of argument expressions, covered by section §6.6 of the Scala Language Specification (SLS):
ArgumentExprs ::= ‘(’ [Exprs] ‘)’
| ‘(’ [Exprs ‘,’] PostfixExpr ‘:’ ‘_’ ‘*’ ’)’
| [nl] BlockExpr
The curly braces are covered by the last case (block expression), which essentially is ‘{’ Block ‘}’
(cf. beginning of chapter 6 SLS).
This doesn't go for conditional expressions, if
, (§6.16 SLS) and while
loop expressions (§6.17 SLS), but it works for for
comprehensions (§6.19 SLS), somewhat of an inconsistency.
A pattern matching statement or pattern matching anonymous functions literal on the other hand must be defined with curly braces, e.g. { case i: Int => i + i }
, parentheses are not allowed here (§8.5 SLS).
In your method call, foreach
takes a function argument, so you can drop the redundant parentheses or double braces:
List(1, 2).foreach({ case i => println(i) })
List(1, 2).foreach {{ case i => println(i) }}
List(1, 2).foreach { case i => println(i) } // no reason to have double braces
In this case, the pattern matching doesn't really buy you anything, and you can use a regular (non-pattern-matching) function, and thus the following would work, too:
List(1, 2).foreach(i => println(i)) // §6.23 SLS - anonymous functions
List(1, 2).foreach(println) // §6.26.2 / §6.26.5 - eta expansion
In your case though, a Map
's map
method passes a tuple of key and value to the function, that's why you use pattern matching (case
statements) to deconstruct that tuple, so you are bound to have curly braces. That is nicer than writing
map1.foreach(tup => println("key " + tup._1 + " value " + tup._2)
As a side note, putting braces around pattern matching case bodies is considered bad style; they are not necessary, even if the body spans multiple lines. So instead of
case(key, value) => { println("key " + key + " value " + value) }
you should write
case (key, value) => println("key " + key + " value " + value)
There is a bit of polemic in this blog post regarding the different variants of using braces, dots and parentheses in Scala (section "What's not to like"). In the end, you are to decide which is the best style—this is where people advocating "opinionated" versus "un-opinionated" languages fight with each other.
In general, you need curly braces when the expression spans multiple lines or if you have a pattern match. When calling methods with multiple parameter lists, often the last list contains one function argument, so you get nice looking—subjective judgment of course—syntax:
val l = List(1, 2, 3)
l.foldLeft(0) {
(sum, i) => sum + i
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With