在clojure中,这是有效的:
(loop [a 5]
(if (= a 0)
"done"
(recur (dec a))))
但是,这不是:
(let [a 5]
(if (= a 0)
"done"
(recur (dec a))))
所以我想知道:为什么循环并让它们分开,因为它们(至少在概念上)引入词法绑定这一事实?也就是说,为什么循环是重复目标,而不是?
编辑:最初编写的“循环目标”,我发现这是不正确的。答案 0 :(得分:5)
考虑以下示例:
(defn pascal-step [v n]
(if (pos? n)
(let [l (concat v [0])
r (cons 0 v)]
(recur (map + l r) (dec n)))
v))
此函数按给定n+m
行计算m
pascal三角形线。
现在,想象一下,let
是recur
目标。在这种情况下,我将无法使用pascal-step
运算符从let
绑定递归调用recur
函数。
现在让我们让这个例子更复杂一点:
(defn pascal-line [n]
(loop [v [1]
i n]
(if (pos? i)
(let [l (concat v [0])
r (cons 0 v)]
(recur (map + l r) (dec i)))
v)))
现在我们正在计算帕斯卡三角形的n
行。如您所见,我在这里需要loop
和let
。
此示例非常简单,因此您可以建议直接使用let
和(concat v [0])
删除(cons 0 v)
绑定,但我只是向您展示这个概念。可能有一个更复杂的例子,let
内的loop
是不可避免的。