Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure `loop`and`with redefs`不能很好地配合使用_Clojure - Fatal编程技术网

Clojure `loop`and`with redefs`不能很好地配合使用

Clojure `loop`and`with redefs`不能很好地配合使用,clojure,Clojure,我有一些代码,我重构了这些代码,却发现有东西被循环破坏了。经过一些调试,我发现循环和与redefs不能很好地配合使用。我意识到在循环中使用redefs可能没有意义,但我没想到它会不起作用。我不确定这是不是有意的 这是我为演示“问题”而创建的MCVE: 这给了我: 重复出现的参数计数不匹配,应为:0个参数,获得:1 使用redefs删除,的效果与预期一致: (loop [test 3] (if (zero? test) "done" (recur (dec test))))

我有一些代码,我重构了这些代码,却发现有东西被
循环
破坏了。经过一些调试,我发现
循环
与redefs
不能很好地配合使用。我意识到在循环中使用redefs可能没有意义,但我没想到它会不起作用。我不确定这是不是有意的

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

这给了我:

重复出现的参数计数不匹配,应为:0个参数,获得:1

使用redefs删除
的效果与预期一致:

(loop [test 3]
  (if (zero? test)
    "done"
    (recur (dec test))))
并返回
“完成”


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

解释是用redefs对
进行宏观扩展:

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

(with-redefs-fn {}
  (fn []
    (if (zero? test)
      "done"
      (recur (dec test)))))    
您可以看到,由于引入了新的
fn
,因此
recur
将引用该
fn
,而不是更远的
循环(这解释了算术异常)

还有许多其他宏以这种方式与
循环
“不兼容”,因为
循环
需要相对于
循环
处于尾部位置,如果
循环
发生在宏调用内,宏可能正在操纵代码,以使
recur
不再处于尾部位置

特别是对于使用redefs的
(以及各种其他情况),解决方法可以是:

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