2009-11-09 14 views
8

Dlaczego skalak (kompilator Scala) nie optymalizuje rekurencji ogona?Dlaczego skalak nie może optymalizować rekurencji ogona w niektórych scenariuszach?

kod i wywołania kompilatora, który demonstruje to:

 
> 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

Zauważ, że optymalizacja podsiodłowa poziomu maszyny JVM jest przeznaczona dla java 7 zobacz http://wikis.sun.com/display/mlvm/TailCalls –

Odpowiedz

12

metod, które można przesłonić NIE może być ogon rekurencyjnej. Spróbuj tego:

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

+1 Jakie są przesłanki? (Mam na myśli to mogę sobie wyobrazić, ale chciałbym wiedzieć) – OscarRyz

+2

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

1

spróbuj tego:

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) 

Uwaga, ifakmoże być rekurencyjny, ale może nie tak dobrze. Oznacz klasę lub metodę końcową, a najprawdopodobniej dokona rekurencji ogonowej.

0

Wewnętrzne funkcje są również uprawnione do całkowitego kosztu posiadania.

Powiązane problemy