Scala中的Futures是否真的有用? [英] Are Futures in Scala really functional?

查看:113
本文介绍了Scala中的Futures是否真的有用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读此博客帖子,声称 Futures code>不是功能,因为它们只是副作用计算的包装器。例如,它们包含RPC调用,HTTP请求等。是否正确?

I am reading this blog post that claims Futures are not "functional" since they are just wrappers of side-effectful computations. For instance, they contain RPC calls, HTTP requests, etc. Is it correct ?

博客文章提供了以下示例:

The blog post gives the following example:

def twoUsersFeed(a: UserHandle, b: UserHandle)
                (implicit ec: ExecutionContext): Future[Html] =
  for {
    feedA <- usersFeed(a)
    feedB <- usersFeed(b)
  } yield feedA ++ feedB

您失去所需的属性:一致的结果(引用透明度)。此外,您失去了尽可能少的请求的属性。很难使用多值请求并具有可组合的代码。

恐怕我不知道。在这种情况下,你能解释一下我们失去一致结果吗?

I am afraid I don't get it. Could you explain how we lose the consistent result in this case ?

推荐答案

博客文章未能在 Future 和它的常用方式,IMO。如果你只写了 Future ,那么你可以用 Future 编写纯函数代码;

The blog post fails to draw a proper distinction between Future itself and the way it's commonly used, IMO. You could write pure-functional code with Future, if you only ever wrote Futures that called pure, total functions; such code would be referentially transparent and "functional" in every remotely reasonable sense of the word.

真正的是未来给你有限的副作用控制,如果你使用它们有副作用的方法。如果您创建未来包装 webClient.get ,则创建 Future 将发送一个HTTP调用。但这不是关于 Future 的事实,这是关于 webClient.get !的事实。

What is true is that Futures give you limited control of side effects, if you use them with methods that have side effects. If you create a Futurewrapping webClient.get, then creating that Future will send a HTTP call. But that's not a fact about Future, that's a fact about webClient.get!

这篇博文中有一个真相。分离表示您的计算执行它,完全,通过例如。自由monad,可以导致更高效和更可测试的代码。例如。您可以创建一个查询语言,其中您表示一个操作,如获取A和B的所有共同的朋友的个人资料照片,而不实际运行它。这使得更容易测试你的逻辑是否正确(因为很容易做一个测试实现,可以运行相同的查询 - 或者甚至只是检查查询对象直接),和我认为的博客文章正在试图建议,意味着你可以eg组合多个请求以获取相同的配置文件。 (这甚至不是纯粹的功能编程关注 - 一些OO书籍有命令模式的想法 - 虽然IME功能编程工具像 for / yield 语法使得以这种方式工作更容易)。如果你有一个 fetchProfile 方法,当运行时,立即触发一个HTTP请求,然后如果你的代码逻辑请求相同的配置文件两次,没有办法避免获取相同的配置文件两次。

There is a grain of truth in this blog post. Separating expressing your computation from executing it, completely, via e.g. the Free monad, can result in more efficient and more testable code. E.g. you can create a "query language", where you express an operation like "fetch the profile photos of all the mutual friends of A and B" without actually running it. This makes it easier to test if your logic is correct (because it's very easy to make e.g. a test implementation that can "run" the same queries - or even just inspect the "query object" directly) and, as I think the blog post is trying to suggest, means you could e.g. combine multiple requests to fetch the same profile. (This isn't even purely a functional-programming concern - some OO books have the idea of a "command pattern" - though IME functional programming tools like for/yield syntax make it much easier to work in this way). Whereas if all you have is a fetchProfile method that, when run, immediately fires off a HTTP request, then if your code logic requests the same profile twice, there's no way to avoid fetching the same profile twice.

但这不是真的未来比帮助更混乱。

But that isn't really about Future per se, and IMO this blog post is more confusing than helpful.

这篇关于Scala中的Futures是否真的有用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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