java.lang.StackOverflowError в хвостовой рекурсии - PullRequest
5 голосов
/ 22 декабря 2011

Я обнаружил ошибку StackOverflowError для следующего кода:

(defn recursive-reverse
  ([coll] (recursive-reverse [coll nil]))
  ([coll acc]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))

хотя использование цикла заставит его работать:

(defn recursive-reverse [lst]
  (loop [coll lst acc nil]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))

Что не так с предыдущим кодом без цикла?

Ответы [ 2 ]

7 голосов
/ 22 декабря 2011

Ваша ошибка здесь:

([coll] (recursive-reverse [coll nil]))

Вы звоните recursive-reverse с одним аргументом (вектором).Это вызывает тот же список аргументов функции, так что он делает это рекурсивно и каждый раз создает кадр стека.

Измените его на:

([coll] (recursive-reverse coll nil))

, и вы должны быть правы.

(Кроме того, отдельная проблема, но я бы обычно делал проверку для nil вместо '() и с использованием next вместо rest. Я не думаю, что это имеет какое-то реальное преимущество с точки зрения производительностиили что-нибудь, но мне кажется, что чище.)

1 голос
/ 22 декабря 2011

Это сработало для меня:

(defn recursive-reverse
  ([coll] (recursive-reverse coll nil))
  ([coll acc]
    (if (= coll '()) acc
        (recur (rest coll) (cons (first coll) acc)))))

Вы передали аргументы recursive-reverse в паре ненужных скобок, вот и все.

...