Когда я пытаюсь добавить метаданные к бесконечной ленивой последовательности в Clojure, я получаю переполнение стека, и если я удаляю метаданные, то это работает просто отлично. Почему добавление макроса with-meta
ломает ленивый seq?
Сначала создайте бесконечное число очень хороших чисел:
(defn good []
(lazy-seq
(cons 42
(good))))
user> (take 5 (good))
(42 42 42 42 42)
Затем добавьте несколько метаданных в каждый из экземпляров lazy-seq:
(defn bad []
(lazy-seq
(cons 42
(with-meta
(bad)
{:padding 4}))))
user> (take 5 (bad))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]
Попробуйте переместить метаданные на один уровень вверх:
(defn also-bad []
(with-meta
(lazy-seq
(cons 42
(also-bad)))
{:padding 4}))
user> (take 5 (foo))
java.lang.StackOverflowError (NO_SOURCE_FILE:0)
[Thrown class clojure.lang.Compiler$CompilerException]
Вот пример метаданных о конечной последовательности:
(defn also-works []
(lazy-seq
(cons 4
(with-meta
()
{:a 5}))))
user> (also-works)
(4)
user> (meta (rest (also-works)))
{:a 5}
user>