Clojure - 测试函数表达式的相等性?

时间:2012-02-22 11:15:23

标签: function clojure expression equality

假设我有以下clojure函数:

(defn a [x] (* x x))

(def b (fn [x] (* x x)))

(def c (eval (read-string "(defn d [x] (* x x))")))

有没有办法测试函数表达式的相等性 - 某些等价于

(eqls a b)

返回true?

3 个答案:

答案 0 :(得分:11)

这完全取决于“函数表达式的相等性”的含义。

这些函数最终将作为字节码,因此我可以将每个函数对应的字节码转储到byte [],然后比较两个字节码数组。

但是,有许多不同的编写语义等效方法的方法,这些方法在字节码中的表示方式不同。

一般来说,如果不运行它,就无法分辨出一段代码。因此,在所有可能的输入上,无法在不运行两个代码的情况下判断两位代码是否相等。

从计算上来说,这至少与停止问题一样糟糕,甚至可能更糟。

暂停问题是不可判定的,所以这里的一般情况答案绝对没有(并且不仅适用于Clojure,而是适用于所有编程语言)。

答案 1 :(得分:3)

我同意上述答案,关于Clojure没有内置的能力来确定两个函数的等价性,并且已经证明你无法在功能上测试程序(也称为黑盒测试)来确定相等由于暂停问题(除非输入集是有限的并且已定义)。

我想指出,即使它们具有不同的形式(不同的字节代码),也可以用代数方式确定两个函数的等价性。

代数证明等价的方法是在1930年由Alonzo Church开发的,并且被称为Lambda微积分中的β减少。这个方法当然适用于你的问题中的简单形式(也会产生相同的字节代码),也适用于产生不同字节代码的更复杂的形式。

答案 2 :(得分:0)

我无法添加其他人的优秀答案,但我想提供另一个帮助我的观点。如果你是测试从你自己的函数返回正确的函数,而不是比较你可能得到的函数对象,只需将函数作为'symbol返回。

我知道这可能不是作者要求的,但对于简单的情况,它可能会这样做。