为什么未来有副作用? [英] Why future has side effects?

查看:109
本文介绍了为什么未来有副作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 FPiS 这本书,作者在页107上说:


我们应该注意到Future没有纯粹的功能性接口。
这就是为什么我们不希望我们的图书馆的用户直接与
处理Future的原因之一。但重要的是,即使
Future上的方法依赖于副作用,我们的整个Par API仍然是纯粹的。只有在用户调用运行并且实现收到一个
ExecutorService(我们公开未来机器)之后,才是
。因此,我们的用户
编程为纯粹的接口,其实现
仍然依赖于一天结束时的效果。但是,由于我们的
API仍然是纯粹的,所以这些效果不是副作用。


为什么Future没有纯粹的功能性接口?

解决方案

问题在于创造一个诱发副作用的Future本身也是一种副作用,渴望自然。



这打破了参照透明度。即如果你创建了一个只能打印到控制台的Future,那么未来将会立即运行并且运行副作用而不会让你问。



一个例子:

 用于{
x< - Future {println(Foo)}
y< - Future {println (Foo)}
} yield()

这会导致Foo印两次。现在如果 Future 是透明的,我们应该可以在下面的非内联版本中得到相同的结果:

 val printFuture = Future {println(Foo)} 

用于{
x< - printFuture
y< - printFuture
$ yield()

然而,这只会打印Foo一次,甚至更成问题,无论您是否包含 for-expression ,都会打印它。

使用引用透明的表达式,我们应该能够在不改变程序的语义的情况下内联任何表达式,Future不能保证这一点,因此它破坏了参照透明性并且本质上有效。


I am reading the book FPiS and on the page 107 the author says:

We should note that Future doesn’t have a purely functional interface. This is part of the reason why we don’t want users of our library to deal with Future directly. But importantly, even though methods on Future rely on side effects, our entire Par API remains pure. It’s only after the user calls run and the implementation receives an ExecutorService that we expose the Future machinery. Our users therefore program to a pure interface whose implementation nevertheless relies on effects at the end of the day. But since our API remains pure, these effects aren’t side effects.

Why Future has not purely functional interface?

解决方案

The problem is that creating a Future that induces a side-effect is in itself also a side-effect, due to Future's eager nature.

This breaks referential transparency. I.e. if you create a Future that only prints to the console, the future will be run immediately and run the side-effect without you asking it to.

An example:

for {
  x <- Future { println("Foo") }
  y <- Future { println("Foo") }
} yield ()

This results in "Foo" being printed twice. Now if Future was referentially transparent we should be able to get the same result in the non-inlined version below:

val printFuture = Future { println("Foo") }

for {
  x <- printFuture
  y <- printFuture
} yield ()

However, this instead prints "Foo" only once and even more problematic, it prints it no matter if you include the for-expression or not.

With referentially transparent expression we should be able to inline any expression without changing the semantics of the program, Future can not guarantee this, therefore it breaks referential transparency and is inherently effectful.

这篇关于为什么未来有副作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆