是否有功能或宏我可以执行以下操作:
(has-side-effects? my-function my-function-args)
:或类似的东西可以返回 true 或 false ,或 {:副作用true / false,:result return_value)
我只需要一种简单的方法来测试哪些功能是无副作用的。
答案 0 :(得分:7)
如果是您的某项功能,请添加一些元数据以标记是否有副作用。
然后您可以使用((meta f) :side-effects)
如果是第三方功能,我无法知道(其他更改其代码以使用上述解决方案)。
实际上,即便如此,但它并不漂亮。您可以使用自己的函数包装该函数,该函数具有元数据。
另外,请记住,除了没有副作用外,纯函数还有一个附加属性。它的评估仅取决于其参数,而不取决于某些全局共享状态,如外部变量或系统时间。您也可以将其添加到元数据中。然后,您可以通过检查两个元数据条目来检查它是否真的是纯粹的。
但是,请注意:
对于将其他函数作为参数的函数,这根本不起作用。这是一个例子:调用map
是否有副作用?
它不在这里:(map inc [1 2 3])
但它确实在这里:(map println [1 2 3])
因为传递的功能可能有也可能没有副作用。
答案 1 :(得分:7)
在一般情况下这是不可能的(除非你设法解决halting problem ...... :-))
但是,您可以考虑在特定情况下使用各种技术:
答案 2 :(得分:5)
Clojure不是纯粹的功能性语言。它不像Haskell那样使用类型系统强制函数的纯度。所以,没有,没有(直截了当的)方法可以知道函数是否在Clojure中是无副作用的。
答案 3 :(得分:-1)
不,没有简单的方法可以肯定地得到“是”或“否”的答案。但是,您可以通过确定是否甚至可能在给定代码中产生副作用来回答“不”或“可能”。
如果您发现任何可能存在副作用的迹象,那么您可以返回“可能”。否则,您将返回“否”,因为没有副作用。
您可以通过查找表明可能发生副作用的表单来查看代码并进行猜测。任何'print','dosync',Java setter或newing-up Java对象都意味着副作用是可能的。
总之,我所知道的是不可能的答案。但是,没有/也许可能是。