zer*_*ing 10 functional-programming scala
我正在阅读FPiS一书,在第107页上,作者说:
我们应该注意到Future没有纯粹的功能界面.这就是为什么我们不希望我们图书馆的用户直接处理Future的部分原因.但重要的是,即使Future上的方法依赖于副作用,我们的整个Par API仍然是纯粹的.只有在用户调用run并且实现接收到我们公开Future机制的ExecutorService之后.因此,我们的用户可以编程为纯粹的界面,但其实现仍然依赖于当天结束时的效果.但由于我们的API仍然纯净,这些效果不是副作用.
为什么Future还没有纯粹的功能界面?
Luk*_*itz 20
问题在于,由于Future的渴望本质,创造一个引起副作用的未来本身也是副作用.
这打破了参考透明度.即如果你创建一个只打印到控制台的Future,将来会立即运行并运行副作用而不需要它.
一个例子:
for {
x <- Future { println("Foo") }
y <- Future { println("Foo") }
} yield ()
Run Code Online (Sandbox Code Playgroud)
这导致"Foo"被打印两次.现在,如果Future引用透明,我们应该能够在下面的非内联版本中获得相同的结果:
val printFuture = Future { println("Foo") }
for {
x <- printFuture
y <- printFuture
} yield ()
Run Code Online (Sandbox Code Playgroud)
然而,这只是打印"Foo"一次,甚至更多的问题,它打印它无论你是否包括for-expression.
使用引用透明表达式,我们应该能够在不改变程序语义的情况下内联任何表达式,Future不能保证这一点,因此它会破坏引用透明性并且本质上是有效的.
据我所知,Future在创建时会自动运行计算.即使它在嵌套计算中缺乏副作用,它仍然会破坏flatMap组合规则,因为它随时间改变状态:
someFuture.flatMap(Future(_)) == someFuture // can be false
Run Code Online (Sandbox Code Playgroud)
除了平等实施问题,我们可以在这里遇到一个竞争条件:新的Future立即运行一小部分时间,并且它isCompleted可以与someFuture已经完成的情况不同.
为了它代表纯洁WRT效果,Future应按照其计算和运行它,只有当用户明确地要求它,就像在的情况下Par(或scalaz的Task).
| 归档时间: |
|
| 查看次数: |
1361 次 |
| 最近记录: |