我的Clojure循环中的尾部位置在哪里?

时间:2016-04-05 18:29:57

标签: clojure tail-recursion

Clojure说我无法从非尾部位置调用recur

这不是尾部位置吗?

在我的循环中尾部位置

(loop [i 20]
    (for [x (range 1 21)]
      (if (zero? (rem i x))
        i
        (recur (+ i 1)))))

2 个答案:

答案 0 :(得分:5)

for没有按照你的想法行事;它不是一个必要的循环。它是列表推导或序列生成器。因此,最后没有返回或迭代调用,因此您无法在其中放置recur

在这个表达式中,您可能根本不需要looprecur; for就是构建序列所需的全部内容,但我并不清楚你想要建立什么序列。

答案 1 :(得分:1)

除了@JohnBaker's answer之外,任何recur指的是(最近的)封闭loopfn(可以打扮成letfn或{ {1}})。你的片段中没有这样的东西。所以defn没有任何东西可以处于尾部位置。

但只需将recur替换为for,即可获得

loop

...评估为(loop [i 20] (loop [x 1] (if (zero? (rem i x)) i (recur (+ i 1))))) ,毫无疑问是你的意图。

但是,外部20永远不会再次出现,因此很可能是loop

let

(let [i 20] (loop [x 1] (if (zero? (rem i x)) i (recur (+ i 1))))) 处于尾部位置,因为通过recur表单在该控制路径中无需执行任何操作:loop表单 返回值。 recur的两个臂都有自己的尾部位置。

还有一些其他伪装的if有自己的尾部位置:ifor是这样的。