2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关如何使用本平台的更多信息,请参阅 关于 页面。

0 投票
ClojureScript
编辑
  1. 怀疑这些 两个循环cljs.core/prefers* 中的用法。我是不是看错了,或者它们总是返回 nil?看起来内层的 when 结果,即递归调用 prefers* 的结果,总是被丢弃。

  2. 此外,如果这两个循环的目的是对 prefers 表的多态查找,那么调用 parents 是否也应该与 在 cljs.core/dominates 中的 isa? 使用相同的 hierarchy?目前,它们是在全局层次结构上进行的。

  3. 另外,如果没有 prefers 表或它为空,您可能可以跳过这两个循环。

1 答案

0 投票

我怀疑这段代码可能源自 MultiFn 中的 Clojure 代码,该代码之前存在层次结构错误(并在 1.11 中修复 - see https://clojure.atlassian.net/browse/CLJ-2234 )。

感谢Alex的回答和指向原始来源的链接。根据Java代码,我的三个问题的答案似乎是'是'。这些应该作为Clojurescript项目的缺陷报告吗?

但是我认为我可能在Java(和CLJS)的实现中看到更多问题。

1. `isa?`不论数据类型,都是一种多态比较:向量以位置处理。对于`prefers`,多态依赖于数据类型。向量不以位置处理,并且在向量上调用`parents`总是返回`nil`。

2. 在[L88][1]处,`preferMethod`确保表中没有冲突的`prefers`。但是对于`prefers`的当前实现,交换`x`和`y`是不够的。如果你首先偏爱关系较低的格,然后是一个更高格的冲突偏爱,你不会得到错误。反过来操作,你则会。

   (def h
     (-> (make-hierarchy)
         (derive ::a ::b)
         (derive ::b ::c)
         (derive ::a ::d)
         (derive ::d ::e)))

   ;; 不会捕获冲突
   (defmulti m1 identity :hierarchy #'h)
   (prefer-method m1 ::b ::a)
   (prefer-method m1 ::d ::b)
   #'user/m1

   ;; 更改prefers的顺序可以捕获冲突
   (defmulti m2 identity :hierarchy #'h)
   (prefer-method m2 ::d ::b)
   (prefer-method m2 ::b ::a)
   执行错误 (IllegalStateException) 在 user/eval137582 (REPL:244)。
   多方法'm2'中的偏好冲突::user/a 已经偏好在 :user/b 之上

[1] https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/MultiFn.java#L88
...