【问题标题】:Identify impure functions in Clojure识别 Clojure 中的不纯函数
【发布时间】:2016-10-20 01:56:53
【问题描述】:

我正在学习 Clojure 和一般的函数式编程(来自 python)。在 Clojure 中,可以创建不纯函数,因为您可以使用 slurp 和其他输入方式。有没有办法在 Clojure 中轻松识别不纯函数,或者只是将这些函数保存在代码的单独部分中?

【问题讨论】:

  • 不是,不是。无论如何,您将如何定义“不纯函数”? memoize 不纯吗? memoize返回的函数呢?还是在内部使用transients 的引用透明函数?
  • Clojure 不是纯粹的 FP 语言,例如 Haskell。如果这对您很重要,那么 Clojure 不是正确的选择。
  • @MichielBorkent:纯洁对我来说并不重要,我只是觉得如果能区分纯洁和不纯洁的部分会很有趣。

标签: clojure functional-programming


【解决方案1】:

有一个很常见的 convention 以 bang 结束函数名称(例如 swap!),其中该函数在 STM 事务中使用是不安全的。这包括 IO 和许多类型的副作用,因此这里与 impurity 有一些重叠,但是,许多 impure 函数也是完全安全的。

【讨论】:

  • 请改写“在 STM 中使用不安全”部分,因为交换是 STM 的一部分 ;-) 它是完全安全的,它只是具有受控的副作用。
  • @ArthurUlfeldt 措辞已经非常类似于库编码标准中的短语:“使用爆炸!仅用于 STM 事务中不安全的事情。”所以我不确定如何改进它。
  • 我真的不希望看到人们避免在 dosync 块中使用 swap!,因为他们认为这将是“不安全的”。我们必须小心不要在此类引发此类谣言的网站上发表声明。您可以选择一个在 STM 中使用实际上不安全的示例,同时明确说明并非所有名称以 ! 结尾的函数都是如此。
  • @ArthurUlfeldt 据我了解,swap! 可能在 dosync 块中执行多次,并且可能多次修改原子,这并不是人们真正想要的。这不正确吗?
  • 这是不正确的。与代理和原子的所有交互都将保持到事务提交并被发送给代理和原子。在特殊情况下,它们被发送零次事务错误。保证它们是安全的。
【解决方案2】:

理论上,没有办法确定函数是否产生副作用(由于莱斯定理)。因此,可能无法区分纯函数和不纯函数。当然,可能有一种方法可以在句法层面检查函数是否绝对不纯,但我怀疑这在实践中是否真的有帮助。

【讨论】:

    猜你喜欢
    • 2014-04-19
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 2016-03-17
    • 2017-06-11
    • 1970-01-01
    相关资源
    最近更新 更多