何时以及如何在clojure中使用独立的层次结构?

Rob*_*lan 12 clojure hierarchy keyword

Clojure用于创建关键字临时层次结构的系统对于花费一些时间使用该语言的大多数人来说都很熟悉.例如,该语言的大多数演示和演示包括诸如的示例

(derive ::child ::parent)
Run Code Online (Sandbox Code Playgroud)

然后他们继续展示如何将其用于多方法调度.

在我看过的所有幻灯片和演示文稿中,他们使用全局层次结构.但是可以通过使用(derived h :: child :: parent)将关键字关系放在独立的层次结构中,其中h由(make-hierarchy)创建.因此,有些问题:

  • 关于何时有用或必要,是否有任何指导方针?
  • 是否有任何操作层次结构的功能?

合并特别有用,所以我这样做:

(defn merge-h [& hierarchies] 
   (apply merge-with (cons #(merge-with clojure.set/union %1 %2) hierarchies))
Run Code Online (Sandbox Code Playgroud)

但我想知道这些功能是否已存在于某处.

编辑:将"自定义"层次结构更改为"独立"层次结构,因为该术语更好地描述了这种动物.此外,我做了一些研究,并在下面包括我自己的答案.欢迎进一步评论.

Rob*_*lan 5

我在最近几天深入研究了这个问题,我想我有一些答案:

  1. 独立层次结构上使用的函数与在全局层次结构上使用相同函数时具有不同的语义.执行(派生kwd1 kwd2)会产生副作用 - 全局层次结构中的条目.另一方面,(派生层次结构kwd1 kwd2)是有效的 - 该函数返回一个新的层次结构,而不是修改一个var.
  2. 使用独立层次结构可以为相同的关键字提供多个不同的层次结构.例如:

    (def篮球等级(派生(make-hierarchy):gretzky:jordan))

    (def hockey-hierarchy(derive(make-hierarchy):jordan:gretzky))

可以表明:jordan在篮球等级中的含义高于:gretzky,而曲棍球等级则相反.

另外:非命名空间关键字可以放入独立的层次结构中,但不能放入全局层次结构中.所以

(derive (make-hierarchy) :a :b)
Run Code Online (Sandbox Code Playgroud)

将起作用,但对于全局层次结构,这些关键字必须位于命名空间中:

(derive :nspace/a :nspace/b)
Run Code Online (Sandbox Code Playgroud)

其中nspace是一些命名空间.(有趣的是,这个名称空间实际上不必在任何地方声明.)

总而言之,当需要多个层次结构时,或者在运行时需要广泛修改层次结构时,应使用独立层次结构.此外,如果我们想要裸体关键字的层次结构,则需要一个独立的层次结构.