为什么不让一个有效的复发目标?

时间:2013-10-04 10:17:15

标签: clojure

在clojure中,这是有效的:

(loop [a 5]
  (if (= a 0)
    "done"
    (recur (dec a))))

但是,这不是:

(let [a 5]
  (if (= a 0)
    "done"
    (recur (dec a))))

所以我想知道:为什么循环并让它们分开,因为它们(至少在概念上)引入词法绑定这一事实?也就是说,为什么循环是重复目标,而不是?

编辑:最初编写的“循环目标”,我发现这是不正确的。

1 个答案:

答案 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三角形线。

现在,想象一下,letrecur目标。在这种情况下,我将无法使用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行。如您所见,我在这里需要looplet

此示例非常简单,因此您可以建议直接使用let(concat v [0])删除(cons 0 v)绑定,但我只是向您展示这个概念。可能有一个更复杂的例子,let内的loop是不可避免的。