繁体   English   中英

为什么在Clojure中`disj`和`dissoc`有不同的功能?

[英]why are `disj` and `dissoc` distinct functions in Clojure?

就我所见,Clojure的核心功能几乎总是适用于不同类型的收集,例如, conjfirstrest等。我有点疑惑为什么disjdissoc不同; 他们有完全相同的签名:

(dissoc map) (dissoc map key) (dissoc map key & ks)
(disj set) (disj set key) (disj set key & ks)

和相当类似的语义。 为什么这些都不是由同一个功能覆盖? 我可以看到支持这一点的唯一一个参数是map有(assoc map key val)(conj map [key val])来添加条目,而sets只支持(conj set k)

我可以编写一个单行函数来处理这种情况,但是Clojure在很多时候都是如此优雅,以至于每当它不是:)时它真的很刺激我

只是为了给Arthur的答案提供一个平衡点: conj甚至更早定义(名称conj出现在core.clj的第82行vsp44的disj和1429的dissoc ),但适用于所有Clojure集合类型。 :-)显然它不使用协议 - 相反它使用常规Java接口,就像大多数Clojure函数一样(事实上我相信目前Clojure中唯一使用协议的“核心”功能是reduce / reduce-kv )。

我猜想,这是由于审美上的选择,而事实上可能与其中地图支持方式conj -是他们支持disj ,人们可能期望其采取可能被传递到同样的参数conj ,这将是问题:

;; hypothetical disj on map
(disj {:foo 1
       [:foo 1] 2 
       {:foo 1 [:foo 1] 2} 3}
       }
      {:foo 1 [:foo 1] 2} ;; [:foo 1] similarly problematic
      )

应该返回{}{:foo 1 [:foo 1] 2}还是{{:foo 1 [:foo 1] 2} 3} conj愉快地接受[:foo 1]{:foo 1 [:foo 1] 2}作为事conj上的地图。 conj有两个地图的论点意味着merge ;事实上merge来讲实现conj ,加入特殊处理nil )。

所以,或许是有意义的有dissoc的地图,这样很明显,它消除了一个关键,而不是“东西,可能是conj “d”。

现在,理论上可以使用dissoc来处理集合,但是也许有人可能会期望它们也支持assoc ,这可能说得不合理。 可能值得指出的是,向量确实支持assoc而不是dissoc ,所以这些并不总是在一起; 这里肯定有一些审美紧张。

尽管我强烈怀疑这是core.clj中的一个引导问题,但尝试回答其他人的动机总是令人怀疑。 这两个函数都是在core.clj中很早就定义的,除了它们各自只采用一种类型并直接在其上调用方法之外几乎相同。

(. clojure.lang.RT (dissoc map key))

(. set (disjoin key))

这两个函数都是在core.clj定义protocal之前定义的 ,因此它们不能使用协议根据类型在它们之间进行分派。 这两个都存在于协议之前的语言规范中。 它们也经常被呼叫,以便有尽可能快地制作它们的强烈动机。

  (defn del
   "Removes elements from coll which can be set, vector, list, map or string"
   [ coll & rest ]
  (let [ [ w & tail ] rest  ]
    (if w 
      (apply del (cond
          (set? coll) (disj coll w)
          (list? coll)  (remove #(= w %) coll)
          (vector? coll) (into [] (remove #(= w % ) coll))
          (map? coll) (dissoc coll w)
          (string? coll) (.replaceAll coll (str w) "")) tail)
            coll)))

谁在乎? 只需使用上面的功能,忘记过去......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM