Почему скаляры не могут оптимизировать хвостовую рекурсию в определенных сценариях?

Почему scalac (компилятор Scala) не оптимизирует хвостовую рекурсию?

Вызовы кода и компилятора, демонстрирующие это:

> кошка foo.scala 
класс Foo {
 def ifak (n: Int, acc: Int): Int = {  
   если (n == 1) в соответствии  
   еще ифак (n-1, n*acc)  
 }
}

> скалак foo.scala
> jd-gui Foo.class
импорт scala.ScalaObject;

публичный класс Foo
  реализует ScalaObject
{
  public int ifak(int n, int acc)
  {
    return ((n == 1)? acc: 
      ифак (n - 1, n * acc));
  }
}

3 ответа

Решение

Методы, которые могут быть переопределены, НЕ могут быть хвостовыми рекурсивными. Попробуй это:

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

Попробуй это:

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)

Заметить, что ifak может быть рекурсивным, но может и не так. Отметьте класс или метод как final, и он, вероятно, станет хвосто-рекурсивным.

Внутренние функции также имеют право на TCO.

Другие вопросы по тегам