Search code examples
scalareturn

Garbage value in Some/None without return statement


Why does the following code (fibonacci series) behave differently if I do not use 'return' statement. I thought that we do not need 'return'.

def nthFibonacci(nth:Int): Option[Int] = {
  @annotation.tailrec
  def go(previousNo:Int, nextNo:Int, currentCount:Int, nth:Int):Option[Int]= {
    if (currentCount == nth) Some(previousNo)
    else go(nextNo,previousNo+nextNo,currentCount+1,nth)
  }

  if (nth<=0) None //invalid argument check
  if (nth==1) Some(0) //first fibonacci
  if (nth == 2) Some(1) //second fibonacci
  go(1,(0+1),2,nth)
}

//for n=0,1 I get garbage while I should get None or Some.

nthFibonacci (0) res0: Option[Int] = Some(1070270178)

nthFibonacci(1) res1: Option[Int] = Some(-2140540357)

nthFibonacci(2) res2: Option[Int] = Some(1)

Interestingly, if I change the code and add 'return', the code works! if (nth<=0) return None //invalid argument check if (nth==1) return Some(0) //first fibonacci if (nth == 2) return Some(1) //second fibonacci go(1,(0+1),2,nth)

nthFibonacci (0)
res0: Option[Int] = None

nthFibonacci(1)
res1: Option[Int] = Some(0)

nthFibonacci(2)
res2: Option[Int] = Some(1)

Another observation is that if I use if/else then the code seem to work fine without return. But I cannot understand why I am forced to write either return or if/else

if (nth<=0) None
  else if (nth == 1) Some(0)
  else if (nth == 2)  Some(1)
  else go(1,(0+1),2,nth)

nthFibonacci (0) //None
nthFibonacci(1) //Some(0)
nthFibonacci(2) //Some(1)

Solution

  • Because that's the way control flow works in Scala. Since go is your last expression, your if-else expression simply returns a value which is being ignored.

    Pattern matching can help here:

    nth match {
      case 0 => None
      case 1 => Some(0)
      case 2 => Some(1)
      case _ => go(1, (0 + 1), 2, nth)
    }
    

    This is an alternative to the if-else expression. If you still want to go with if-else, make sure to include an else in your last branch.