In Scala I tend to favour writing large chained expressions over many smaller expressions with val
assignments. At my company we've sort of evolved a style for this type of code. Here's a totally contrived example (idea is to show an expression with lots of chained calls):
import scala.util.Random val table = (1 to 10) map { (Random.nextInt(100), _) } toMap def foo: List[Int] = (1 to 100) .view .map { _ + 3 } .filter { _ > 10 } .flatMap { table.get } .take(3) .toList
Daniel Spiewak's Scala Style Guide (pdf), which I generally like, suggests the leading dot notation in the chained method calls may be bad (see doc: Method Invocation / Higher-Order Functions), though it doesn't cover multi-line expressions like this directly.
Is there another, more accepted/idiomatic way to write the function foo
above?
UPDATE: 28-Jun-2011
Lots of great answers and discussion below. There doesn't appear to be a 100% "you must do it this way" answer, so I'm going to accept the most popular answer by votes, which is currently the for comprehension approach. Personally, I think I'm going to stick with the leading-dot notation for now and accept the risks that come with it.
The example is slightly unrealistic, but for complex expressions, it's often far cleaner to use a comprehension:
def foo = { val results = for { x <- (1 to 100).view y = x + 3 if y > 10 z <- table get y } yield z (results take 3).toList }
The other advantage here is that you can name intermediate stages of the computation, and make it more self-documenting.
If brevity is your goal though, this can easily be made into a one-liner (the point-free style helps here):
def foo = (1 to 100).view.map{3+}.filter{10<}.flatMap{table.get}.take(3).toList //or def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList
and, as always, optimise your algorithm where possible:
def foo = ((1 to 100).view map {3+} filter {10<} flatMap {table.get} take 3).toList def foo = ((4 to 103).view filter {10<} flatMap {table.get} take 3).toList def foo = ((11 to 103).view flatMap {table.get} take 3).toList
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