user1934513
user1934513

Reputation: 725

Scala function return behaviour

I'm trying to solve this epfl scala course homework where they ask me to write the sum of a list. I can do it if I use return statements or if use match statement but I can't understand why it wouldn't work using if/else without return statement.

def sum(xs: List[Int]): Int = xs {
  if (xs.isEmpty) {
    0
  } else {
    xs.head + sum(xs.tail)
  }
}

The run time error that I get when I run sum(List(1,3,2)) is

java.lang.IndexOutOfBoundsException: 0
  at scala.collection.LinearSeqOptimized.apply(LinearSeqOptimized.scala:67)
  at scala.collection.LinearSeqOptimized.apply$(LinearSeqOptimized.scala:65)
  at scala.collection.immutable.List.apply(List.scala:89)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)
  at example.Lists$.sum(Lists.scala:39)

If I replace 0 in the code with 100 the error message changes to java.lang.IndexOutOfBoundsException: 100 . It's like it is trying to access the N'th element of the list and all I need is a return. If I add the two return statements all works as expected.

Can you please shed some light ?

Upvotes: 0

Views: 87

Answers (1)

jrook
jrook

Reputation: 3519

The root cause is in the first line of the function declaration:

def sum(xs: List[Int]): Int = xs {

This is equivalent with:

def sum(xs: List[Int]): Int = xs.apply(<Some function>) 

For example xs.apply(3) means get item with index 3 from the list xs.

Scala will evaluate the code inside the brackets and will try to apply the result to xs. As it unwinds the recursion, it will eventually get to an empty list, but the program is asking it to return xs(0) which does not exist thus the IndexOutOfBoundsException error.

To make this program do what you intend it to do, just remove the xs from the beginning of your function body:

def sum(xs: List[Int]): Int = {

Now:

sum(List(1,3,2))
res0: Int = 6

Upvotes: 6

Related Questions