Clojure中的懒惰评估问题

时间:2009-12-13 03:49:21

标签: clojure

它在REPL中尝试了以下内容并且没有错误(因为延迟评估):

(defn square [n] (* n n))
  (if (= 0 0) 
    (println "hello")
    (map square ["a" "b"]))

以下是错误(因为它得到了评估):

(defn square [n] (* n n))
  (if (= 0 1)
    (println "hello")
    (map square ["a" "b"]))

我担心的是,如果在一大段代码中,有些部分我的测试用例永远无法触及,那么例如,上面的代码会在生产中崩溃! 有没有办法在编译时检查这些东西?

由于

2 个答案:

答案 0 :(得分:10)

这不是懒惰的评价。这是有条件的评估。

特殊格式(if condition expr1 expr2)仅在条件为假时评估expr2。

你的担忧与Clojure和懒惰无关。

在Ruby中试试这个:

irb(main):003:0> raise "wannabe error" if false
=> nil  

[编辑:更准确地回答您的问题]

在编译时,您很难用动态语言检测错误。

在运行时,您可以使用不同的条件值评估测试,以达到可能的所有重要代码分支。我想所有动态语言的情况都是一样的。这就是我们为其编写测试的原因。

因此,您希望涵盖您在测试中关注的条件,包括真假两种情况。

我个人喜欢像QuickCheck这样的解决方案,它们可以生成各种可能的值(如果需要,可以通过某些条件保护)以进行测试。在上面的例子中,你只想测试2个案例,无论是真还是假,但想象一下由各种输入值触发的其他测试。不幸的是,这种发电机的实现并不多。我知道动态类型语言的唯一QuickCheck克隆用于Erlang(专有且非常昂贵)和Ruby的RushCheck。 Clojure实现在infancy

答案 1 :(得分:4)

不。然后,如果代码在未经测试用例测试的情况下表现不佳,则不会被测试用例捕获。

你可以使用宏在Clojure上添加一个类型系统,但是你会遇到类型系统所具有的限制以及它所带来的限制。

(旁注:这不是非常懒惰的评价;这是if特殊形式的行为)