I think there is @tailrec
annotation to ensure the compiler will optimize a tail recursive function. Do you just put it in front of the declaration? Does it also work if Scala is used in scripting mode (for instance using :load <file>
under REPL)?
I think there is @tailrec annotation to ensure the compiler will optimize a tail recursive function.
A method annotation which verifies that the method will be compiled with tail call optimization. If it is present, the compiler will issue an error if the method cannot be optimized into a loop. Source tailrec.scala Since. 2.8.
Scala 2.7. x supports tail-call optimization for self-recursion (a function calling itself) of final methods and local functions.
From the "Tail calls, @tailrec and trampolines" blog post:
- In Scala 2.8, you will also be able to use the new
@tailrec
annotation to get information about which methods are optimised.
This annotation lets you mark specific methods that you hope the compiler will optimise.
You will then get a warning if they are not optimised by the compiler.- In Scala 2.7 or earlier, you will need to rely on manual testing, or inspection of the bytecode, to work out whether a method has been optimised.
Example:
you could add a
@tailrec
annotation so that you can be sure that your changes have worked.
import scala.annotation.tailrec class Factorial2 { def factorial(n: Int): Int = { @tailrec def factorialAcc(acc: Int, n: Int): Int = { if (n <= 1) acc else factorialAcc(n * acc, n - 1) } factorialAcc(1, n) } }
And it works from the REPL (example from the Scala REPL tips and tricks):
C:\Prog\Scala\tests>scala Welcome to Scala version 2.8.0.RC5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_18). Type in expressions to have them evaluated. Type :help for more information. scala> import scala.annotation.tailrec import scala.annotation.tailrec scala> class Tails { | @tailrec def boom(x: Int): Int = { | if (x == 0) throw new Exception("boom!") | else boom(x-1)+ 1 | } | @tailrec def bang(x: Int): Int = { | if (x == 0) throw new Exception("bang!") | else bang(x-1) | } | } <console>:9: error: could not optimize @tailrec annotated method: it contains a recursive call not in tail position @tailrec def boom(x: Int): Int = { ^ <console>:13: error: could not optimize @tailrec annotated method: it is neither private nor final so can be overridden @tailrec def bang(x: Int): Int = { ^
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With