【问题标题】:adding metadata to a lazy sequence将元数据添加到惰性序列
【发布时间】:2010-11-06 13:31:59
【问题描述】:

当我尝试将元数据添加到 Clojure 中的无限惰性序列时,我遇到了堆栈溢出,如果我删除元数据,那么它就可以正常工作。为什么添加 with-meta 宏会破坏惰性序列?

首先创建一个非常好的数字的无限序列:

(定义好 [] (惰性序列 (缺点 42 (好的)))) 用户>(取5(好)) (42 42 42 42 42)

然后,为每个惰性序列实例添加一些元数据:

(定义不好 [] (惰性序列 (缺点 42 (带元 (坏的) {:padding 4})))) 用户>(取5(坏)) java.lang.StackOverflowError (NO_SOURCE_FILE:0) [抛出类 clojure.lang.Compiler$CompilerException]

尝试将元数据上移一级:

(定义也不好 [] (带元 (惰性序列 (缺点 42 (也很糟糕))) {:填充 4})) 用户>(取 5 (foo)) java.lang.StackOverflowError (NO_SOURCE_FILE:0) [抛出类 clojure.lang.Compiler$CompilerException]

这是一个有限序列上的元数据示例:

(定义也有效 [] (惰性序列 (缺点 4 (带元 () {:a 5})))) 用户>(也有效) (4) user> (meta (rest (also-works))) {:a 5} 用户>

【问题讨论】:

  • lazy-seq 和 with-meta 都是宏,因此您应该能够通过 macroexpand resp 获得更深入的了解。宏展开-1.

标签: lisp clojure lazy-sequences


【解决方案1】:

因为LazySeq 会在您在LazySeq 上调用withMeta 时立即评估其主体。你会失去你的懒惰。

public final class LazySeq extends Obj implements ISeq, List{
    ...
    public Obj withMeta(IPersistentMap meta){
        return new LazySeq(meta, seq());
    }
    ...
}

seq() 评估惰性序列的主体(如果尚未评估)。您上面的代码在连续的惰性序列上不断调用with-meta,它会评估它们,直到堆栈爆炸。我认为目前没有任何方法可以将元数据添加到惰性序列而不导致其评估其主体。

【讨论】:

  • FWIW,CLJ-1800 中的第二个补丁,如果被接受,将提供一种方法。
猜你喜欢
  • 1970-01-01
  • 2016-11-06
  • 2021-11-17
  • 2011-07-21
  • 2021-12-22
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多