Clojure - 测试函数表达式的相等性?
假设我有以下 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)
return true ?
Suppose I have the following clojure functions:
(defn a [x] (* x x))
(def b (fn [x] (* x x)))
(def c (eval (read-string "(defn d [x] (* x x))")))
Is there a way to test for the equality of the function expression - some equivalent of
(eqls a b)
returns true?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这恰恰取决于“函数表达式的相等性”的含义。
这些函数最终将作为字节码,因此我可以将每个函数对应的字节码转储到 byte[],然后比较两个字节码数组。
然而,有许多不同的方式来编写语义上等效的方法,这些方法在字节码中不会有相同的表示。
一般来说,如果不运行一段代码,就不可能知道它的用途。因此,如果不对所有可能的输入运行这两个代码,就不可能判断这两个代码是否等效。
从计算角度来说,这至少与停机问题一样糟糕,甚至可能更糟。
暂停问题是无法确定的,因此这里的一般情况答案肯定是否定的(不仅对于 Clojure,而且对于每种编程语言)。
It depends on precisely what you mean by "equality of the function expression".
These functions are going to end up as bytecode, so I could for example dump the bytecode corresponding to each function to a byte[] and then compare the two bytecode arrays.
However, there are many different ways of writing semantically equivalent methods, that wouldn't have the same representation in bytecode.
In general, it's impossible to tell what a piece of code does without running it. So it's impossible to tell whether two bits of code are equivalent without running both of them, on all possible inputs.
This is at least as bad, computationally speaking, as the halting problem, and possibly worse.
The halting problem is undecidable as it is, so the general-case answer here is definitely no (and not just for Clojure but for every programming language).
我同意上述答案,因为 Clojure 没有内置的能力来确定两个函数的等价性,并且已经证明,您无法通过功能测试程序(也称为黑盒测试)来确定相等性,因为停止问题(除非输入集是有限的并且已定义)。
我想指出的是,可以通过代数确定两个函数的等价性,即使它们具有不同的形式(不同的字节码)。
用代数证明等价性的方法是由 Alonzo Church 在 1930 年代开发的,被称为 Lambda 微积分中的 beta 约简。此方法当然适用于您问题中的简单形式(这也会产生相同的字节代码),也适用于会产生不同字节代码的更复杂的形式。
I agree with the above answers in regards to Clojure not having a built in ability to determine the equivalence of two functions and that it has been proven that you can not test programs functionally (also known as black box testing) to determine equality due to the halting problem (unless the input set is finite and defined).
I would like to point out that it is possible to algebraically determine the equivalence of two functions, even if they have different forms (different byte code).
The method for proving the equivalence algebraically was developed in the 1930's by Alonzo Church and is know as beta reduction in Lambda Calculus. This method is certainly applicable to the simple forms in your question (which would also yield the same byte code) and also for more complex forms that would yield different byte codes.
我无法补充其他人的出色答案,但想提供另一种对我有帮助的观点。例如,如果您要测试从您自己的函数返回的函数是否正确,那么您可能只需将函数作为
'symbol
返回,而不是比较函数对象。我知道这可能不是作者所要求的,但对于简单的情况可能会这样做。
I cannot add to the excellent answers by others, but would like to offer another viewpoint that helped me. If you are e.g. testing that the correct function is returned from your own function, instead of comparing the function object you might get away with just returning the function as a
'symbol
.I know this probably is not what the author asked for but for simple cases it might do.