【问题标题】:Should a delay be considered as an immutable value?延迟是否应该被视为不可变的值?
【发布时间】:2012-05-29 00:26:50
【问题描述】:
我是 Clojure / 使用不可变值编程的函数式方法的忠实粉丝。
但是我不确定 delay 是否应该被视为不可变值(假设您延迟纯函数)。我对较大的不可变数据结构中存在一个或多个延迟的情况特别感兴趣。
例如一个包含延迟的向量:
[1 2 (delay (reduce + (range 1000)))]
据我所见,它的行为就好像它是一个不可变的值,因为在您强制其评估之前您无法看到延迟的结果 - 然后结果被缓存并且该值永远不会改变之后。
以这种方式将延迟视为不可变值有什么问题吗?
【问题讨论】:
标签:
clojure
functional-programming
immutability
lazy-evaluation
【解决方案1】:
延迟模拟通常称为 thunk 的东西,它是对尚未评估的表达式的引用,一旦被强制,它就会被其结果替换,此后是不可变的。 Haskell 使用这种内部可变的 thunk 来模拟非严格评估。表达式[1, 2, foldl1 (+) [0..1000]] 名义上与其在具有严格评估的语言中的显式延迟等效项相同。
当然前提是延迟对象中使用的函数是纯函数,将其视为不可变也没有什么坏处。您可以从以下几个方面考虑:
根据定义,纯函数可以替换为其结果。
局部突变(在本例中为延迟对象)不会使函数不纯。
当然,Clojure 不区分纯函数和不纯函数,因此作为开发人员,您需要认真对待它。
【解决方案2】:
delay 是“价值生产者”,就像函数是价值生产者一样,只是 delay 使“价值生产者代码”延迟执行,即当它被要求提供值时,而不变性是正在生成的值的属性,因此可以将生成的值视为不可变的,就像它是函数调用一样。这是关于产生的价值,但如果你的函数正在产生副作用,那么你可能会遇到其他问题,但产生的价值仍然是不可变的