内部懒惰序列究竟如何正常工作

srn*_*tea 3 clojure

我是clojure的新手,并不清楚内部是如何完成懒惰序列的工作,或者更具体的是返回延迟序列的函数意味着只有在需要时才会计算结果.例如,在以下示例中:

(defn fc-lazy [ fn xs ]
 (lazy-seq
  (if-let [ xss (seq xs) ]
   (cons (fn (first xs)) (fc-lazy fn (rest xs)))
  ())))
Run Code Online (Sandbox Code Playgroud)

我打电话的时候:

(fc-lazy #(* % 2) (range 100))
Run Code Online (Sandbox Code Playgroud)

结果将是100个数字的集合,这意味着fc-lazy函数将被调用100次,这对我来说是不清楚的; 在这种情况下,我们已经堆叠了所有这100个函数,如果不是,为什么?

谢谢.

Thu*_*ail 6

我想它就是这样的.

lazy-seq

  • 将其表达式形式参数转换为函数形式,
  • 将它编译成Clojure闭包(invoke符合IFn接口的JVM类上的方法 )
  • 将此函数类绑定到一个新LazySeq对象,
  • 为其实现的序列留下一个空洞.

在此阶段,不是评估产生序列的表达式,而是将表达式捕获为看起来像(因此是)序列的对象中的函数对象.

当需要实现序列的某些函数(例如firstnext或)seq被调用时LazySeq,

  • 它注意到空洞并调用捕获的闭包,
  • 用结果填补洞,
  • 应用所需功能的
  • 结果返回.

后续调用找到填充的孔,并立即返回其所需的方面.

因此,当你完成序列时,你会得到你的一百个电话,但一次一个,而不是一次完成.


如果需要任何更正,我将不胜感激.