在她的演讲中,The Future Of Clojure Bodil提出以下主张:
盖·斯蒂尔(Guy Steele)在ICFP上发表了名为Organizing Functional Code for Parallel Execution (or, foldl and foldr Considered Slightly Harmful)的演讲(也称为in ACM)。
Guy Steele在幻灯片70中断言:
一旦您说“ first,SUM = 0
”,您就被迫了。
累加器对并行性不利。请注意,foldl
和
foldr
尽管具有功能,但从根本上说是累积的。
这很有趣。因此,博迪尔说盖伊·斯蒂尔(Guy Steele)提出了一个问题。然后,她声称Rich用Reducers(和Transducers)解决了这个问题。在16:11的the Transducers talk中,我们看到Rich谈到了一些有关foldr
的特殊论文。
鸟-Lectures on Constructive Functional Programming(1988)
赫顿-A tutorial on the universality and expressiveness of fold(1999)
Rich有效地表示fold
是可组合的-您可以使用它们来构建其他更高阶的函数,例如map
和filter
。
我的问题是-Bodil对吗? Rich解决了Guy Steele提出的问题吗?减速器(在Clojure中)是否解决了Guy Steele概述的结垢文件夹累积问题?
最佳答案
是的,reducer确实解决了这个问题,因为它们的语义与Guy Steele所指的折叠类型略有不同(尽管实际上效果可能非常相似)。foldr
和foldl
采用单个函数参数,该参数依次应用于集合的每个成员(以及累加器值)。正如Steele所说,它们本质上是顺序的(这就是为什么拥有“ left”和“ right”变体才有意义的原因)。 Clojure的clojure.core/reduce
函数也是如此。
另一方面,clojure.core.reducers/fold
接受两个函数参数,归约函数和合并函数。将集合分为多个块,使用缩减功能对每个区块进行缩减,然后使用合并功能合并这些结果。图形上看起来像这样:
(此图来自我的书Seven Concurrency Models in Seven Weeks,其中包括关于Reducers的部分)。
有时,您可以使用单个函数进行归约和合并(例如,对整数序列求和)。但是在其他情况下,这是不可能的。
当同时使用单个函数进行归约和合并时,当且仅当归约/合并函数具有关联性时,clojure.core.reducers/fold
将给出与顺序折叠相同的结果。