Scala中的Futures真的有用吗?

Mic*_*ael 6 concurrency functional-programming scala future

我读这个博客帖子的索赔Futures没有"功能性",因为它们都只是包装侧面effectful计算.例如,它们包含RPC调用,HTTP请求等.它是否正确?

博客文章给出了以下示例:

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

you lose the desired property: consistent results (the referential transparency). Also you lose the property of making as few requests as possible. It is difficult to use multi-valued requests and have composable code.

我恐怕没有得到它.你能解释一下我们consistent result在这种情况下输了吗?

lmm*_*lmm 12

博客文章未能在Future其自身和常用方式(IMO)之间进行适当区分.你可以编写纯函数代码Future,如果你只编写了Future一个名为纯函数的函数; 这样的代码在每个远程合理意义上都是引用透明和"功能"的.

什么是真正的是,Future小号给你的副作用有限的控制,如果你用的是有副作用的方法中使用它们.如果您创建一个Future包装webClient.get,那么创建Future它将发送一个HTTP调用.但这不是事实Future,这是事实webClient.get!

这篇博客文章中有一点道理.通过例如Free monad完全分离表达你的计算与执行它,可以产生更高效和更可测试的代码.例如,您可以创建一个"查询语言",您可以在其中表达"获取A和B的所有共同朋友的个人资料照片"而不实际运行它的操作.这样可以更容易地测试您的逻辑是否正确(因为它很容易制作,例如可以"运行"相同查询的测试实现 - 甚至只是直接检查"查询对象"),并且,我认为博客文章试图建议,意味着您可以组合多个请求来获取相同的配置文件.(这甚至不是纯粹的函数式编程问题 - 一些OO书籍有一个"命令模式"的想法 - 尽管像for/ yieldsyntax 这样的IME函数式编程工具使得以这种方式工作变得更容易).然而,如果您拥有的是一种fetchProfile方法,在运行时立即触发HTTP请求,那么如果您的代码逻辑请求两次相同的配置文件,则无法避免两次获取相同的配置文件.

但这Future本身并不是真的,IMO这篇博文更令人困惑而不是有用.