假设我有以下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?
答案 0 :(得分:11)
这完全取决于“函数表达式的相等性”的含义。
这些函数最终将作为字节码,因此我可以将每个函数对应的字节码转储到byte [],然后比较两个字节码数组。
但是,有许多不同的编写语义等效方法的方法,这些方法在字节码中的表示方式不同。
一般来说,如果不运行它,就无法分辨出一段代码。因此,在所有可能的输入上,无法在不运行两个代码的情况下判断两位代码是否相等。
从计算上来说,这至少与停止问题一样糟糕,甚至可能更糟。暂停问题是不可判定的,所以这里的一般情况答案绝对没有(并且不仅适用于Clojure,而是适用于所有编程语言)。
答案 1 :(得分:3)
我同意上述答案,关于Clojure没有内置的能力来确定两个函数的等价性,并且已经证明你无法在功能上测试程序(也称为黑盒测试)来确定相等由于暂停问题(除非输入集是有限的并且已定义)。
我想指出,即使它们具有不同的形式(不同的字节代码),也可以用代数方式确定两个函数的等价性。
代数证明等价的方法是在1930年由Alonzo Church开发的,并且被称为Lambda微积分中的β减少。这个方法当然适用于你的问题中的简单形式(也会产生相同的字节代码),也适用于产生不同字节代码的更复杂的形式。
答案 2 :(得分:0)
我无法添加其他人的优秀答案,但我想提供另一个帮助我的观点。如果你是测试从你自己的函数返回正确的函数,而不是比较你可能得到的函数对象,只需将函数作为'symbol
返回。
我知道这可能不是作者要求的,但对于简单的情况,它可能会这样做。