2024 年 Clojure 调查问卷中分享您的想法!

欢迎!有关如何工作的更多信息,请查看关于页面。

0
ClojureScript

在扩展记录的协议时,在某些情况下递归方法永远不会终止。

`
(defrecord R [a])

(defprotocol P
(f [x]))

(extend-protocol P
R
(f [x]

(if x
  (recur nil)
  x))

default
(f [x]

(if x
  (recur nil)
  x)))

(prn (f 1)) ; #1
(prn (f (R. 1))) ; #2
`

{{prn}} 调用 #1 按预期打印 {{nil}},但 {{prn}} 调用 #2 永远不会终止。

看起来编译器在 {{while}} 循环中创建了一个分配给 {{this}} 的变量,使得对 "{{x}}" 的测试始终真正测试 {{this}},而应该测试通过 {{recur}} 调用传入的 {{x}} 的值。

注:我在 ClojureScript 1.8.51 上进行测试。上面 "影响版本" 字段仅给出 1.7.228 作为最新版本。

3 答案

0

评论:bstiles

实际上,“当它应该测试通过 recur 调用传入的 'x' 的值时始终真正测试 'this'” 只有当由 x 表示的值的类型保持不变时才是真实的。如果,如在示例中那样,类型发生改变,调用应该被派发到适当匹配的方法实现。

这似乎在 Clojure 中表现如预期。

0

评论:dnolen

与 Mike Fikes 确认,即使在 recur 扩展后,master 版本上仍然存在此问题。

0
参考:https://clojure.atlassian.net/browse/CLJS-1644(由 alex+import 报告)
...