Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 为什么let不是一个有效的重现目标?_Clojure - Fatal编程技术网

Clojure 为什么let不是一个有效的重现目标?

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

在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-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完全相同,只是它也充当重现目标。看见