В Scala 2.8.x добавлена новая аннотация (@tailrec
), которая дает ошибку времени компиляции, если компилятор не может выполнить оптимизацию хвостового вызова для аннотированного метода.
Есть ли в Clojure аналогичное средство в отношении loop/recur
?
EDIT:
После прочтения первого ответа на мой вопрос (спасибо, Божидар Бацов) и дальнейшего поиска в документации Clojure, я наткнулся на это:
(повторяющиеся выражения *)
Оценивает выражения по порядку, а затем параллельно связывает привязки точки рекурсии со значениями выражений. Если точка рекурсии была методом fn, то она повторно связывает параметры. Если точка рекурсии была циклом, то она повторно связывает привязки цикла. Затем выполнение возвращается к точке рекурсии. Выражение recur должно точно соответствовать арности точки рекурсии. В частности, если точка рекурсии была вершиной метода variadic fn, сбор аргументов покоя отсутствует - должен быть передан один seq (или ноль). возврат в другое положение, кроме хвоста, является ошибкой .
Обратите внимание, что recur является единственной циклической конструкцией без использования стека в Clojure . Оптимизация хвостовых вызовов отсутствует, и использование самостоятельных вызовов для зацикливания неизвестных границ не рекомендуется. recur работает, и его использование в хвостовой позиции проверяется компилятором [выделено мной].
(def factorial
(fn [n]
(loop [cnt n acc 1]
(if (zero? cnt)
acc
(recur (dec cnt) (* acc cnt))))))