Why is this an exception?

... even though it is tail-optimized?

def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean = { val one = stream1.read() val two = stream2.read() if(one != two) false else if(one == -1 && two == -1) true else areStreamsEqual(stream1, stream2) } 

Is there a way to get the Scala compiler to perform tail call optimization here?

+4
source share
2 answers

Thanks pst for the comment about @tailrec. Given that the scala compiler error message explains the reason for not optimizing the method.

 <filename>.scala:64: error: could not optimize @tailrec annotated method: it is neither private nor final so can be overridden def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean = 

makes the method private to sort it

I suspect that at the byte code level there are two commands for calling methods: virtual_call and tail_call.

+6
source

For those trying to recreate a compiler error in REPL, you need to wrap the method in a class like this:

 class Test { @annotation.tailrec def areStreamsEqual(stream1: InputStream, stream2: InputStream): Boolean = { val one = stream1.read() val two = stream2.read() if(one != two) false else if(one == -1 && two == -1) true else areStreamsEqual(stream1, stream2) } } 

If you just connect the method to REPL, it will be TCO'd just fine, since the method outside the class cannot be overridden.

+1
source

All Articles