Wenn ich versuche, Metadaten zu einer unendlichen Lazy-Sequenz in Clojure hinzuzufügen, bekomme ich einen Stack-Überlauf, und wenn ich die Metadaten entferne, funktioniert es gut. Warum bricht das Hinzufügen des with-meta
Makros die Lazy Seq?Hinzufügen von Metadaten zu einer Lazy-Sequenz
Zuerst eine unendliche seq von einer sehr schönen Nummer schaffen:
(defn good [] (lazy-seq (cons 42 (good)))) user> (take 5 (good)) (42 42 42 42 42)
Dann einige Metadaten zu jedem der lazy-Seq-Instanzen hinzufügen:
(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]
Versuchen Sie, die Meta-Daten auf ein bewegtes Ebene:
(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]
Hier ist ein Beispiel von Meta-Daten auf einer endlichen Folge:
(defn also-works [] (lazy-seq (cons 4 (with-meta () {:a 5})))) user> (also-works) (4) user> (meta (rest (also-works))) {:a 5} user>
Lazy-Seq und With-Meta sind Makros, also sollten Sie mit Makroexpand bzw. Makroexpand-1. – Svante