2009-11-09 11 views
8

¿Por qué Scalac (el compilador Scala) no optimiza la recursividad de cola?¿Por qué Scalac no puede optimizar la repetición de cola en ciertos escenarios?

código y compilador invocaciones que demuestra esto:

 
> cat foo.scala 
class Foo { 
def ifak(n: Int, acc: Int):Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
} 
} 

> scalac foo.scala 
> jd-gui Foo.class 
import scala.ScalaObject; 

public class Foo 
    implements ScalaObject 
{ 
    public int ifak(int n, int acc) 
    { 
    return ((n == 1) ? acc : 
     ifak(n - 1, n * acc)); 
    } 
} 
+1

tenga en cuenta que la optimización del tailcall del nivel de JVM se contribuye para java 7, consulte http://wikis.sun.com/display/mlvm/TailCalls –

Respuesta

12

métodos que se pueden sustituir no puede ser recursiva cola. Prueba esto:

class Foo { 
    private def ifak(n: Int, acc: Int): Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
    } 
} 
+0

+1 ¿Cuál es el fundamento? (Quiero decir, me lo puedo imaginar, pero me gustaría saber) – OscarRyz

+2

@OscarRyz: ver http://stackoverflow.com/questions/4785502/why-wont-the-scala-compiler-apply-tail-call-optimization- unless-a-method-is-fina –

1

Prueba esto:

class Foo { 
    def ifak(n: Int, acc: Int):Int = { 
    if (n == 1) acc 
    else ifak(n-1, n*acc) 
    } 
} 

class Bar extends Foo { 
    override def ifak(n: Int, acc: Int): Int = { 
    println("Bar!") 
    super.ifak(n, acc) 
    } 
} 

val foobar = new Bar 
foobar.ifak(5, 1) 

en cuenta que ifak pueden ser recursivas, pero puede que no también. Marque la clase o el método final, y probablemente hará que la cola sea recursiva.

0

Las funciones internas también son elegibles para TCO.

Cuestiones relacionadas