2009-11-09 21 views
8

Pourquoi scalac (le compilateur Scala) n'optimise pas la récursivité de la queue?Pourquoi le scalac ne peut-il pas optimiser la récurrence de la queue dans certains scénarios?

invocations du Code et du compilateur qui fait la démonstration:

 
> 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

notez que l'optimisation des appels de queue JVM est apportée pour java 7 voir http://wikis.sun.com/display/mlvm/TailCalls –

Répondre

12

méthodes qui peuvent être surchargées ne peuvent pas être récursive queue. Essayez ceci:

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

+1 Quelle est la logique? (Je veux dire je peux l'imaginer, mais je voudrais savoir) – OscarRyz

+2

@OscarRyz: voir http://stackoverflow.com/questions/4785502/why-wont-the-scala-compiler-apply-tail-call-optimization- sauf si-une-méthode-est-fina –

1

Essayez ceci:

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) 

Notez que ifakpeut être récursive, mais il ne peut pas aussi bien. Marquer la classe ou la méthode finale, et elle devra probablement être récursive en queue.

0

Les fonctions internes sont également éligibles pour TCO.