2

The method in the class below assumes that y is positive:

class Calculator {
  def addPos(x: Int, y: Int): Int = {
    if (y == 0) x
    else {
      val temp: Int = x + 1
      if (temp < x) throw new OverflowException
      else addPos(temp, y - 1)
    }
  }
}

It is tail recursive and adds one to x from y in each recursion until y is 0. It also throws when be exceed Int.MaxValue. I know that there is a far simpler implementation of this function that doesn't need recursion, BUT, I want to find out why this method causes a StackOverflowError when I do:

val newCalc = new Calculator
println(newCalc.addPos(0, Int.MaxValue))

I thought that since it's tail recursive, the method could not cause an SOError.

Sahand
  • 7,980
  • 23
  • 69
  • 137
  • 2
    Can you paste a stack trace? Does it compile when you add the `@tailrec` annotation? – Thilo Feb 27 '19 at 11:56
  • 3
    I thought it wouldn't matter that I extracted a method from a class and presented it to you as a function, but apparently it does. So I've updated the question to show what I'm actually running. Please see my edit. – Sahand Feb 27 '19 at 12:06
  • 1
    Interesting. Does it work if you move it into an `object`? Or make it `final`? Other than it getting confused by the potential need for dynamic dispatch I cannot see why it would not work. Does the `@tailrec` annotation compile? – Thilo Feb 27 '19 at 12:11
  • 1
    You'll probably get this error for `@tailrec`: https://stackoverflow.com/questions/4785502/why-wont-the-scala-compiler-apply-tail-call-optimization-unless-a-method-is-fin?rq=1 – Thilo Feb 27 '19 at 12:13

0 Answers0