Я читал вопросы других людей о проблемах с переполнением стека в 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))))
В «counts» хранится карта, первоначально полученная из функции «countted-origlabels». На карте есть строковые ключи и целочисленные значения. Его длина составляет около 600 элементов, и значения обновляются во время итерации, но длина остается неизменной, я это проверил.
Функция "orig-gen-pair" читает из файла и возвращает короткую пару последовательностей, по 10 или около того элементов в каждой.
Функция "write-newlabels" просто записывает переданную последовательность на диск и не имеет никаких других побочных эффектов и не возвращает значение.
«Пар-ключевые слова» возвращает короткую последовательность и обновленную версию карты «подсчетов».
Я просто не понимаю, какая ленивая последовательность может вызывать здесь проблему!
Любые советы будут очень признательны!
----РЕДАКТИРОВАТЬ----
Привет всем, я обновил свою функцию, чтобы (надеюсь) она стала немного более идиоматичной 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). Трассировка стека для меня ничего не значит, кроме того, что она наверняка указывает на происходящий беспорядок, связанный с ленивой последовательностью. Есть еще советы? Нужно ли мне публиковать код для функций, которые обрабатывают вызовы песни? Спасибо!