Может ли Scala выполнить хвостовую рекурсию для различных методов, которые вызывают друг друга? - PullRequest
1 голос
/ 15 марта 2012

Я что-то делал с иерархической структурой данных, и я разработал группу методов для ее обхода / анализа с косвенной рекурсией, как описано ниже.

Существуют методы a, b, c и d, все с типом возврата Unit. Метод a вызывается первым. В зависимости от данных он что-то сделает, а затем либо остановится, либо вызовет один из b/c/d. То же самое с каждым из b, c и d - каждый метод может либо остановить, либо вызвать любой из 3 других методов. Итак, какие методы вызываются, и порядок их выполнения будет неизвестен до времени выполнения, и рекурсия не является непосредственно очевидной, поскольку ни один метод не вызывает непосредственно сам себя (не волнуйтесь, каждый метод будет прокомментирован для описания циклической / рекурсивной природы вызовы).

Каждый дополнительный вызов a, b, c или d - это последнее, что нужно выполнить в каждом методе, но это не буквально последний оператор каждого метода; будет оператор if или case, который определяет, какой из них будет вызываться.

Может ли компилятор Scala анализировать эту многоуровневую цепочку вызовов и реализовывать для нее хвостовую рекурсию, учитывая, что ни один метод не вызывает сам себя?

Ответы [ 2 ]

4 голосов
/ 15 марта 2012

Нет, Scala не может выполнить такую ​​оптимизацию хвостового вызова; JVM на самом деле не делает это возможным (или, по крайней мере, нелегким).

Вы можете имитировать это самостоятельно, написав одну функцию, которая может принимать четыре различных пути, в зависимости от аргументов. (Если бы вам помог компилятор, он бы сделал что-то вроде этого.)

1 голос
/ 16 марта 2012

Хотя компилятор не может сделать это автоматически для вас, ваш сценарий использования должен быть пригоден для использования scala.util.control.TailCalls.

Хотя это будет не очень эффективно, и если ваши звонки идут только на 4, это может не стоить этого.

...