它在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"]))
我担心的是,如果在一大段代码中,有些部分我的测试用例永远无法触及,那么例如,上面的代码会在生产中崩溃! 有没有办法在编译时检查这些东西?
由于
答案 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特殊形式的行为)