【问题标题】:What happened with lazy evaluation of ClojureClojure 的惰性求值发生了什么
【发布时间】:2012-06-28 23:57:42
【问题描述】:

我正在以 clojure 方式扭曲我的旧 java/python 头。请帮我理解clojure的惰性特性。

=> (def myvar (lazy-seq [1 2 (prn "abc")]))
#'user/myvar

以上内容很容易理解。由于它是一个惰性序列,因此 (prn "abc") 不会被评估,因此不会打印任何内容。

=> (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”尚未定义。

请任何人指出我的理解正确的方法。

【问题讨论】:

    标签: clojure lazy-evaluation


    【解决方案1】:

    当clojure阅读器找到时

     (def myvar (lazy-seq [1 2 (prn undefined-var)]))
    

    它需要编译它,这就是它抛出错误的原因,因为未定义 undefined-var。在第一种情况下,它可以编译,但直到您使用 seq 才会执行。

    【讨论】:

    • 在 Clojure 中是否就是这种情况,因为 clojure 脚本必须在执行之前编译为 java ?在其他 Lisp 方言中,可以在惰性求值上下文中使用 undefined var 吗?
    • 嗨,John,对不起,我没有使用其他 Lisps 的经验。
    • 感谢 dAni,您的回答很有帮助。但我只能将一个设置为“已接受”。帕维尔更适合我的大脑。
    【解决方案2】:

    以上两个答案都为您提供了有关该主题的良好信息,但我将尝试在此处确定关键问题。当你在 REPL 上写一个s-expression 时,比如(+ x 2),会发生两件事:

    1. the reader解析产生形式的字符,例如符号,
    2. evaluation 的表格。

    惰性求值推迟了第二步,但在第一步中,当阅读器遇到undefined-var 时,它会尝试将其转换为符号,并发现该符号未定义。

    【讨论】:

    • 谢谢帕维尔。它变得更加清晰。源代码需要在读者阶段解析为表单。该错误仅显示解析过程失败。听起来这与“懒惰”的评估无关。也一定是所有lisp方言的通用方式。
    • 没错。据我所知,阅读器几乎是任何列表方言的必备部分。
    【解决方案3】:

    您似乎理解正确,只是 lazy-seq 函数不是这样工作的 这是一个典型的例子:

    user> (lazy-seq (cons 4 (range 5)))
    (4 0 1 2 3 4)
    

    lazy-seq 几乎总是采用 cons 表达式,其中第一个参数 是序列中的第一项,第二个参数是代码 生成列表的其余部分。人们很少需要使用lazy-seq 直接在日常 Clojure 中使用 map reducefilter 等形式 等更常见。

    函数中用于生成序列其余部分的代码也需要 为了能够被编译,在你的情况下你也可以延迟编译 通过使用 eval 虽然我建议不要使用 eval 来处理这样的事情 在其他人需要阅读的代码中;不过,这有助于很好的学习;-)

    user> (def myvar (lazy-seq (cons 1 (eval '(prn undefined-var))))) ; don't do this at work
    #'user/myvar
    user> myvar
    ; Evaluation aborted.
    user> 
    

    【讨论】:

      猜你喜欢
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多