What happened with lazy evaluation of Clojure
我正在扭旧的Java/Python头。请帮助我理解Clojure的懒惰特征。
1 2 | => (def myvar (lazy-seq [1 2 (prn"abc")])) #'user/myvar |
以上内容很容易理解。因为它是一个懒惰的序列,所以(prn"abc")不会被评估,因此不会打印任何内容。
1 2 | => (def myvar (lazy-seq [1 2 (prn undefined-var)])) CompilerException java.lang.RuntimeException: Unable to resolve symbol: undefined-var in this context, compiling:(NO_SOURCE_PATH:1) |
如您所见,以上将引发错误。为什么?
我(错误)的理解是,因为它是懒惰的,(prn undefined var)可以合法存在于这里,即使"undefined var"还没有被定义。
请任何人指出我的理解是正确的。
当陪审员发现
1 | (def myvar (lazy-seq [1 2 (prn undefined-var)])) |
它需要编译它,这就是它抛出错误的原因,因为未定义的var没有定义。在第一种情况下,它编译为OK,但只有在使用seq之后才会执行。
以上两个答案都为您提供了关于这个主题的很好的信息,但我将尝试在这里找出关键问题。当您在诸如
懒惰的评价构成了第二步,但在第一步,当读者遇到
你似乎有正确的理解,只是这不是lazy seq函数的工作原理。下面是一个典型的例子:
1 2 | user> (lazy-seq (cons 4 (range 5))) (4 0 1 2 3 4) |
生成序列其余部分的函数中的代码也需要为了能够编译,在您的情况下,您也可以延迟编译使用
1 2 3 4 5 | user> (def myvar (lazy-seq (cons 1 (eval '(prn undefined-var))))) ; don't do this at work #'user/myvar user> myvar ; Evaluation aborted. user> |