gpt4 book ai didi

clojure - `loop` 和 `with-redefs` 不能一起玩

转载 作者:行者123 更新时间:2023-12-02 06:47:52 28 4
gpt4 key购买 nike

我有一些代码,我重构后才发现 loop 有问题。经过一些调试后,我发现 loopwith-redefs 不能很好地协同工作。我意识到在循环中使用 with-redefs 可能没有意义,但我没想到它不起作用。我不确定这是不是故意的。

这是我为演示“问题”而创建的 MCVE:

(loop [test 3]
(with-redefs []
(if (zero? test)
"done"
(recur (dec test)))))

这给了我:

Mismatched argument count to recur, expected: 0 args, got: 1

删除 with-redefs 按预期工作:

(loop [test 3]
(if (zero? test)
"done"
(recur (dec test))))

并返回“完成”

第一段代码不起作用的原因是什么?这是故意的吗?

最佳答案

解释在with-redefs的宏展开中:

(macroexpand-1
'(with-redefs []
(if (zero? test)
"done"
(recur (dec test)))))

返回:

(with-redefs-fn {}
(fn []
(if (zero? test)
"done"
(recur (dec test)))))

在那里你可以看到,因为引入了一个新的 fnrecur 将引用那个 fn 而不是更远的-away loop(解释了 arity 异常)。

还有其他各种宏与loop“不兼容”,因为recur相对于需要在尾部位置>loop,如果 recur 发生在宏调用中,则宏可能正在操纵代码,使得 recur 不再位于尾部位置。

特别是对于 with-redefs(以及各种其他情况),解决方法可能是:

(loop [test 3]
(let [[recur? val]
(with-redefs []
(if (zero? test)
[false "done"]
[true (dec test)]))]
(if recur?
(recur val)
val)))

关于clojure - `loop` 和 `with-redefs` 不能一起玩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53262649/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com