clojure - 是否应将延迟视为不可变值?

标签 clojure functional-programming immutability lazy-evaluation

我非常喜欢使用不可变值进行编程的 Clojure/函数式方法。

但是我不确定 delay应该被认为是一个不可变的值(假设你延迟了一个纯函数)。我对较大的不可变数据结构中存在一个或多个延迟的情况特别感兴趣。

例如包含延迟的向量:

[1 2 (delay (reduce + (range 1000)))]

据我所知,它的行为就好像它是一个不可变的值,因为在您强制对其进行评估之前您看不到延迟的结果 - 然后结果被缓存并且该值永远不会改变之后。

以这种方式将延迟视为不可变值是否存在任何问题?

最佳答案

延迟模拟通常称为 thunk 的东西,它是对尚未计算的表达式的引用,一旦被强制,它就会被其结果替换,此后是不可变的。 Haskell 使用这种内部可变的 thunk 来模拟非严格评估。表达式 [1, 2, foldl1 (+) [0..1000]] 在名义上与其在具有严格评估的语言中的显式延迟等价物相同。

当然,前提是延迟对象中使用的函数是纯函数,将其视为不可变的没有坏处。您可以通过几种方式来考虑这一点:

  • 根据定义,纯函数可以用其结果替换。

  • 局部突变(在本例中为延迟对象)不会使函数变得不纯。

当然,Clojure 不区分纯函数和非纯函数,因此作为开发人员,您需要勤奋学习。

关于clojure - 是否应将延迟视为不可变值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10791762/

相关文章:

具有多个子命令的 Clojure CLI

haskell - 如何让 Haskell 计算正确的多态类型?

javascript - 函数式 javascript 读取、异步、写入结果

validation - 验证不可变字段

scala - 使用 val 声明的主构造函数参数允许更改值

clojure.core : . 运算符、defmacro 和 setMacro

dynamic - 为什么 Clojure 1.3 在我将变量声明为动态时说变量没有声明为动态?

clojure - 如何在 Clojure 中读取 stdin 中的所有行

functional-programming - 过程式编程和函数式编程有什么区别?

functional-programming - 如何编写不更改状态的应用程序(使用功能语言)?