Основной вопрос: я рассматриваю наиболее значительное применение оптимизации хвостовых вызовов (TCO) как перевод рекурсивного вызова в цикл (в случаях, когда рекурсивный вызов имеет определенную форму). Точнее, при переводе на машинный язык это обычно означает перевод в какую-то серию скачков. Некоторые компиляторы Common Lisp и Scheme, которые компилируют собственный код (например, SBCL), могут идентифицировать хвостовой рекурсивный код и выполнять этот перевод. JVM-based Lisps, такие как Clojure и ABCL, не могут этого сделать. Что такое JVM как машина, которая мешает или затрудняет это? Я не понимаю. Очевидно, что JVM не имеет проблем с циклами. Это компилятор, который должен выяснить, как сделать TCO, а не машину, с которой она компилируется.
Связанный с этим вопрос: Clojure может преобразовать, по-видимому, рекурсивный код в цикл: он действует так, как будто он выполняет TCO, если программист заменяет хвостовой вызов функции ключевым словом recur
. Но если можно получить компилятор для идентификации хвостовых вызовов - например, как SBCL и CCL, то почему компилятор Clojure не может понять, что он должен рассматривать хвостовой вызов так, как он относится к recur
?
(Извините - это, несомненно, FAQ, и я уверен, что вышеприведенные замечания показывают мое невежество, но я не смог найти более ранние вопросы.)