Clojure 是否支持循环重复形式?

Does Clojure support the loop repeat form?

我有以下 Common Lisp 代码片段:

(loop repeat len
  do
    (rotatef
      (nth (random len) list)
      (nth (random len) list))
  finally
    (return list)))))

我想 运行 使用 Clojure。

无论如何,编译器告诉我

loop requires a vector for its binding

这到底是什么意思?我必须在哪里引入向量?

这是你使用循环的方式:

(loop [n 0]
  (if (> n 10)
    n
    (recur (inc n))))

"loop requires a vector for its binding"消息来自循环的第一个参数,在上面的例子中是[n 0],这是一个向量,说我们初始化变量 n 为 0。稍后当我们使用 recur 时,我们的意思是我们想要使用新值 n 重复循环体。

提醒,loop in clojure是一个向量的函数,一些表达式作为主体:

 (loop [bindings*] exprs*)

洗牌

您的示例的目的是随机排列列表。为了完整起见,在 Common Lisp 中,您可以使用 alexandria:shuffle to perform the same task on generalized sequences and the equivalent function in clojure is clojure.core/shuffle.

循环构造

有一个名为 clj-iter which is inspired by CL's iterate function, which itself is a based on loop. However, people tend to avoid 的库在 Clojure 中使用了此类结构,并且更喜欢函数式组合等。

Clojure 是一种独立的语言

只有像 (+ 3 4) 这样非常琐碎的表达式才能被解析和解释为 Clojure 和 Common Lisp 代码。 Clojure 不会尝试以任何方式与现有的 Lisp 或 Scheme 语言兼容,并且有自己的计算模型,不鼓励使用可变结构,就像在您的示例中使用 rotatef 所做的那样。因此,将 Common Lisp 代码移植到 Clojure 需要重新设计现有代码,就像您必须在 Scala 中重写它一样(或 Python 或 Ruby)。

ABCL

我真的不知道你要执行什么,但是如果你想 运行 JVM 上的 Common Lisp 代码,你可以使用 ABCL (Armed Bear Common Lisp),这是一个高效的实现Java.

中的 CL