Я читал вопросы других людей о проблемах переполнения стека в Clojure, и проблема, как правило, заключается в том, что где-то создается ленивая последовательность. Кажется, здесь проблема, но я не могу понять, где я живу.
Вот код, а после кода немного пояснения:
(defn pare-all []
"writes to disk, return new counts map"
(loop [counts (counted-origlabels)
songindex 0]
(let [[o g] (orig-gen-pair songindex)]
(if (< songindex *song-count*) ;if we are not done processing list
(if-not (seq o) ;if there are no original labels
(do
(write-newlabels songindex g);then use the generated ones
(recur counts (inc songindex)))
(let [{labels :labels new-counts :countmap} (pare-keywords o g counts)] ;else pare the pairs
(write-newlabels songindex labels)
(recur new-counts (inc songindex))))
counts))))
Существует карта, хранящаяся в «счетах», первоначально полученная из функции «счетные оригами». Карта имеет строковые ключи и целочисленные значения. Это 600 или около того элементов длиной, и значения обновляются во время итерации, но длина остается той же, я это подтвердил.
Функция «orig-gen-pair» читает из файла и возвращает короткую пару последовательностей, по 10 или около того элементов в каждой.
Функция «write-newlabels» просто записывает переданную последовательность на диск и не имеет никаких других побочных эффектов, а также не возвращает значение.
«Pare-Keywords» возвращает короткую последовательность и обновленную версию карты «count».
Я просто не понимаю, какая ленивая последовательность может быть причиной проблемы здесь!
Любые советы будут очень признательны!
---- EDIT ----
Привет всем, я обновил свою функцию, чтобы она (надеюсь) стала немного более идиоматичной Clojure. Но моя первоначальная проблема все еще остается. Во-первых, вот новый код:
(defn process-song [counts songindex]
(let [[o g] (orig-gen-pair songindex)]
(if-not (seq o) ;;if no original labels
(do
(write-newlabels songindex g);then use the generated ones
counts)
(let [{labels :labels new-counts :countmap} (pare-keywords o g counts)] ;else pare the pairs
(write-newlabels songindex labels)
new-counts))))
(defn pare-all []
(reduce process-song (counted-origlabels) (range *song-count*)))
Это все еще заканчивается на java.lang.StackOverflowError (repl-1: 331). Трассировка стека ничего не значит для меня, за исключением того, что, кажется, указывает на то, что происходит беспорядочная последовательность событий. Есть еще советы? Нужно ли публиковать код в функциях, которые вызывает песня процесса? Спасибо!