14

In a lot of Scala examples I see people use curly braces in places I find outright strange, when the same statement could easily be written using parentheses.

Example:

lst foreach (x => println(s"the value returned is: $x")) // parens
lst foreach {x => println(s"you get the idea, $x")} // braces

I understand that you can use braces as an alternative to parentheses, simply because it allows you to write a statement on multiple lines:

val res = for {
  x <- coll1
  y <- coll2
} yield (x, y) 
  • So when it's written on a single line, is there any inherent reason to use one over the other?
  • The outcome should be the same in the end, or am I missing something?
  • Or is it simply just a matter of style and/or personal taste?
Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • 1
    Besides `foreach`, when currying functions, using `{ }` allows you to create (sort of) new control structures if the last parameter is a function. Is is really useful in practice. – VH-NZZ Jul 03 '14 at 15:15
  • Actually, read up Chap. 9 of _Programming in Scala_ by Odersky et al. – VH-NZZ Jul 03 '14 at 15:20

3 Answers3

17

In general, there are many cases when you would prefer curly braces (e.g. multiline expressions, for comprehensions), but let's talk specifically about

when it's written on a single line, is there any inherent reason to use one over the other

In a second case it's not just curly braces, instead of parentheses, it's curly braces with ommited parentheses. Scala allows you to ommit parenthesis sometimes, and the later syntax is used to access to the niceties you got in partial functions (namely, pattern matching), so

lst foreach {x => println(s"you get the idea, $x")}

is actually

lst foreach({x => println(s"you get the idea, $x")})

which, as I said, can be useful from pattern matching POV:

val map = Map("foo" -> "bar")
map foreach { case (k, v) => println(s"key: $k, value: $v") }
// which is not possible with the usual parenthesis
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
  • I left out the "case" version on purpose, since it seemed redundant to include – Electric Coffee Jul 03 '14 at 12:40
  • 1
    Even with the initial qualifier this is a little misleading—there are lots of places where you either need one or the other (e.g. `for`-comprehensions don't allow `({ ... })`) or where parentheses just don't work (`match`). – Travis Brown Jul 03 '14 at 13:13
  • @TravisBrown agree, there're many other cases, but op asked specifically about *when it's written on a single line, is there any inherent reason to use one over the other?* Will add disclaimer though. – om-nom-nom Jul 03 '14 at 13:19
2

It's an issue of coding style. Have a look at http://www.codecommit.com/scala-style-guide.pdf.

If the function you're passing is a single expression, you can use either and the result will be the same. However, if the function includes multiple expressions you have to use braces. For this reason I always prefer using braces, aside from the fact that I find it makes your intent clearer. (Note that we're talking single expression, not single line. For example:

lst map (x => findInDatabase(x)
               .getOrElse(ERROR_VALUE))

would be fine (since findInDatabase(x).getOrElse(ERROR_VALUE) is a single expression even though it's split into multiple lines.

Also, if the function is currently a single expression and later you need to change it to be multiple expressions, you have to remember to change the parentheses to braces (one more thing to remember).

Mario Camou
  • 2,303
  • 16
  • 28
0

You can only use curly braces when the function only takes one argument. The idea is to make a method call feel more like a control abstraction. So yes you are right it is really a matter of style.

Jim Collins
  • 270
  • 2
  • 8