Clojure 为什么let不是一个有效的重现目标?
在clojure中,这是有效的:Clojure 为什么let不是一个有效的重现目标?,clojure,Clojure,在clojure中,这是有效的: (loop [a 5] (if (= a 0) "done" (recur (dec a)))) 然而,这不是: (let [a 5] (if (= a 0) "done" (recur (dec a)))) 所以我想知道:既然循环和let都(至少在概念上)引入了词汇绑定,为什么它们是分开的?也就是说,为什么循环是重现目标,而let不是 编辑:我注意到最初写的“循环目标”不正确。考虑以下示例: (defn pascal
(loop [a 5]
(if (= a 0)
"done"
(recur (dec a))))
然而,这不是:
(let [a 5]
(if (= a 0)
"done"
(recur (dec a))))
所以我想知道:既然循环和let都(至少在概念上)引入了词汇绑定,为什么它们是分开的?也就是说,为什么循环是重现目标,而let不是
编辑:我注意到最初写的“循环目标”不正确。考虑以下示例:
(defn pascal-step [v n]
(if (pos? n)
(let [l (concat v [0])
r (cons 0 v)]
(recur (map + l r) (dec n)))
v))
此函数通过给定的m
th行计算pascal三角形的n+m
th行
现在,想象一下,let
是一个recurr
目标。在这种情况下,我将无法使用recur
操作符从let
绑定递归调用pascal步骤
函数本身
现在让我们把这个例子稍微复杂一点:
(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行。正如您所看到的,我在这里需要循环
和让
这个示例非常简单,因此您可以建议直接使用
(concat v[0])
和(cons 0 v)
删除let
绑定,但我只是向您展示这个概念。可能有一个更复杂的例子,let
在循环中
是不可避免的。好的,我明白你的意思。但是,为什么Recurr没有一个额外的可选参数来指定跳转到哪个目标?或者这会不会太偏向goto的方向(我们都知道Dijkstra是怎么说goto的)?@jjpe let不是一个重复出现的目标,因为loop是。若let是一个重现目标,那个么循环将不存在。loop与let完全相同,只是它也充当重现目标。看见