Размер стека, насколько я понимаю, зависит от используемой вами JVM, а также от платформы. Если вы используете Sun JVM, вы можете использовать параметры -Xss
и -XThreadStackSize
для установки размера стека.
Предпочтительный способ сделать рекурсию в Clojure, хотя это использовать loop
/ recur
:
(defn fact [x]
(loop [n x f 1]
(if (= n 1)
f
(recur (dec n) (* f n)))))
Clojure выполнит для этого оптимизацию хвостового вызова; это гарантирует, что вы никогда не столкнетесь с StackOverflowError
s.
И поскольку defn
подразумевает привязку loop
, вы можете опустить выражение loop
и использовать его аргументы в качестве аргумента функции. И чтобы сделать его функцией с 1 аргументом, используйте multiary
характеристику функций :
(defn fact
([n] (fact n 1))
([n f]
(if (<= n 1)
f
(recur (dec n) (* f n)))))
Редактировать: Для записи вот функция Clojure, которая возвращает ленивую последовательность всех факториалов:
(defn factorials []
(letfn [(factorial-seq [n fact]
(lazy-seq
(cons fact (factorial-seq (inc n) (* (inc n) fact)))))]
(factorial-seq 1 1)))
(take 5 (factorials)) ; will return (1 2 6 24 120)