4

Clojure で次の関数を定義しました。

; return the input unchanged
(defn same [x] x)

; Recursively call the function on the input N times
(defn recurse-n-times [input function n]
  (if (= n 0)
    input
    (recurse-n-times (function input) function (- n 1))
  )
)

ここに私の再帰関数からのいくつかの出力があります:

(recurse-n-times 0 inc 5)     ; returns 5, as expected
(recurse-n-times 0 same 5)    ; returns 0, as expected
(recurse-n-times 0 same 5000) ; StackOverflowError:
                              ; clojure.lang.Numbers$LongOps.combine
                              ; (Numbers.java:394)

を取得する理由がわかりませんStackOverflowError。最後に行うのrecurse-n-timesは自分自身の呼び出しであるため、末尾再帰を使用し、スタックをまったく拡張しないことを期待しています。

、この代替定義が以下を与えることを期待しますStackOverflowError:

(defn bad-recurse-n-times [input function n]
  (if (= n 0)
    input
    (function (alt-recurse-n-times input function (- n 1)))
  )
)

recurse-n-times末尾再帰を使用しないのはなぜですか?

4

2 に答える 2

4

clojure.orgによると

末尾呼び出しの最適化はありません。recur を使用してください。

したがって、それを行うには「recur」特殊フォームを使用する必要があります。

于 2013-09-07T22:01:38.620 に答える