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

jjp*_*jpe 6 clojure

在clojure中,这是有效的:

(loop [a 5]
  (if (= a 0)
    "done"
    (recur (dec a))))
Run Code Online (Sandbox Code Playgroud)

但是,这不是:

(let [a 5]
  (if (= a 0)
    "done"
    (recur (dec a))))
Run Code Online (Sandbox Code Playgroud)

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

编辑:最初写的"循环目标"我注意到是不正确的.

Leo*_*tny 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))
Run Code Online (Sandbox Code Playgroud)

此函数n+m按给定的m行计算pascal三角形的第一行.

现在,想象一下,这let是一个recur目标.在这种情况下,我将无法使用运算符以绑定方式递归调用pascal-step函数本身.letrecur

现在让我们让这个例子更复杂一点:

(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)))
Run Code Online (Sandbox Code Playgroud)

现在我们正在计算n一个pascal三角形的线.如你所见,我需要两者loop和let这里.

这个例子很简单,所以你可能会建议取消let使用绑定(concat v [0])和(cons 0 v)直接,但我只是显示你的概念.可能有一个更复杂的例子,其中leta内部loop是不可避免的.

  • @jjpe let不是一个重复目标,因为循环是.如果let是复现目标,则循环不存在.循环与let完全相同,除了它还充当重复目标.见http://clojure.org/special_forms#loop (5认同)