关于clojure CollReduce协议的问题

发布于 2022-09-05 08:48:40 字数 1131 浏览 21 评论 0

最近在看七周七并发模型,现在第三章第三节化简器卡住了,没有函数式编程经验。作者这一章使用了coljure这门语言来实现map reduce并发模型。具体实现的时候用到了clojure的协议,源代码如下(去掉了无关的代码):

(ns reducers.core
  (:require [clojure.core.protocols :refer [CollReduce coll-reduce]]
            [clojure.core.reducers :refer [CollFold coll-fold]]))

(defn my-reduce
  ([f coll] (coll-reduce coll f))
  ([f init coll] (coll-reduce coll f init)))

(defn make-reducer [reducible transformf]
  (reify
    CollReduce
    (coll-reduce [_ f1]
      (coll-reduce reducible (transformf f1) (f1)))
    (coll-reduce [_ f1 init]
      (coll-reduce reducible (transformf f1) init))))

(defn my-map [mapf reducible]
  (make-reducer reducible
    (fn [reducef]
      (fn [acc v]
        (reducef acc (mapf v))))))

这里我有几个不是很明白的地方
一、是这个coljure协议本身,以上面的my-reduce为例,书里的例子是这样的:

reducers.core => (my-reduce + [1 2 3 4])
10

书里说coljure协议跟java的接口很像,所以这里的应该是[]这个数据结构本身实现了CollReduce协议吗?
二、是这个复杂的my-map和make-reduce的实现,这里的make-reducer实现了coll-reduce协议,是否是使用了递归?说实话这个实现我是头雾水,完全不明白是怎么工作的。
三、这里咨询一下读过这本书的大佬,是否需要先简单学习一下Clojure?我看作者后面很多章节也使用了Coljure

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吝吻 2022-09-12 08:48:40

没有看过这本书。从代码来看,试试看回答这个问题:

  1. 协议 protocol 是一种 Java 接口,但它额外的能力是可以动态被已知类扩展,而不需要静态实现。my-reduce 函数的实现说明 PersistentVector ([]) 扩展过 CollReduce 协议。
  2. make-reducer 函数倒并不复杂,它简单地委托(delegate)了 CollReduce 协议实现给参数 reducible(也就是说 reducible 是满足 CollReduce协议的)。它的有趣之处是用 transformf 参数(这应该是一个 transducer 函数)来对函数f1 包装,从而让 make-reducer 支持了 transducer 函数。注意 my-map 的实现完全是简化过的 clojure.core 中的 map 函数,它其实不算复杂,是 transducer 函数的标准写法,但其参数栈的定义次序是有奥秘的,具体解释起来就太长,需要理解 transducer 的设计思路。另外,引用的代码应该本身是试图解释 transducer 的设计实现,因此答案就在你的书中。
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文