Это код lisp, который использует рекурсию хвоста.Рекурсия хвоста в clojure
(defun factorial (f n)
(if (= n 1)
f
(factorial (* f n) (- n 1))))
Я переводил это в код clojure, ожидая такой же оптимизации хвостовой рекурсии.
(defn fact [f n]
(if (= n 1)
f
(fact (* f n) (dec n))))
Однако я получил это целочисленное переполнение (не переполнение стека) даже с небольшим числом, таких как (fact 1 30)
.
ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow (Numbers.java:1374)
Я пробовал с recur
, но получил ту же ошибку.
(defn factorial [f n]
(if (= n 1)
f
(recur (* f n) (dec n))))
Что не так с кодом clojure?
Также стоит отметить, что Clojure, из-за ограничений JVM, не поддерживает автоматическую оптимизацию хвостового вызова. 'recur' - это действительно способ найти рекурсивную идиому в этом случае. – JohnJ
Где в документах clojure я могу найти примеры использования recur без цикла? То, как вы использовали его здесь. – SultanLegend