I completely agree with the answer of Peter Pudlak. But for what it's worth, there is a way out: Define a helper method to return a wrapper function for tailrectest:
import scala.annotation.tailrec object Test extends App { def tailrectest_ = tailrectest _ @tailrec def tailrectest(i: Int): Int = i match { case i if i > 0 => { val x = () => tailrectest_(10) tailrectest(i - 1) } case 0 => 0 } }
This adds some noise to the code, but at least it works.
However, if what you are trying to do is build some kind of continuation, your real world code will certainly have to fix some local context in the closure, which excludes my solution above. In this case, I do not see an easy way out.
UPDATE (March 11, 2013):
Petr Pudlak found a similar but superior solution in another question: http://stackoverflow.com/questions/15334611/how-to-make-a-tail-recusive-method-that-can-also-refer-to-itself-in-a-non-tail-r By using an inner function, we can actually capture local state, which make it fully usable. Here is his solution, applied to entropyslave original question: import scala.annotation.tailrec object Test extends App { def tailrectest(i: Int): Int = { @tailrec def tailrectestImpl(i: Int): Int = { i match { case i if i > 0 => val x = () => tailrectest(10) tailrectestImpl(i - 1) case 0 => 0 } } tailrectest( i ) } }
source share