Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the Scala annotation to ensure a tail recursive function is optimized?

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)?

like image 833
huynhjl Avatar asked Jun 24 '10 21:06

huynhjl


People also ask

What annotation ensures the Scala compiler will apply tail recursion optimizations?

I think there is @tailrec annotation to ensure the compiler will optimize a tail recursive function.

What is Scala annotation Tailrec?

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.

Does Scala have tail-call optimization?

Scala 2.7. x supports tail-call optimization for self-recursion (a function calling itself) of final methods and local functions.


1 Answers

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 = {                     ^ 
like image 171
VonC Avatar answered Oct 21 '22 10:10

VonC