请在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

实际上,“.setItem始终测试`this`而不是通过`recur`调用传递进来的x的值”只有在x表示的值的类型保持相同的情况下才成立。如果,如示例中所示,类型发生改变,调用应该调度到匹配的方法实现。

这在Clojure中表现得似乎是正确的。

0

评论者:dnolen

与Mike Fikes确认,即使在递归增强后,master版本上此仍然是一个问题。

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