【问题标题】:Does Clojure support the loop repeat form?Clojure 是否支持循环重复形式?
【发布时间】:2015-11-02 05:48:23
【问题描述】:

我有以下 Common Lisp 代码的 sn-p:

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

我想使用 Clojure 运行。

不管怎样,编译器告诉我的

循环需要一个向量来绑定

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

【问题讨论】:

  • 请注意,此 sn-p 不会执行有效的随机播放。如果您确实想要真正的洗牌,请使用 Fisher-Yates 方法。这并不难。
  • Clojure 和 Common Lisp 是非常不同的语言。代码无法翻译或移植。您需要重新开发大多数代码。不要期望语言结构是兼容的。大多数情况下他们不是。最好为其语言结构使用 Clojure 参考。

标签: loops clojure common-lisp


【解决方案1】:

这就是你使用循环的方式:

(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*)

【讨论】:

    【解决方案2】:

    洗牌

    您的示例的目的是对列表进行洗牌。为了完整起见,在 Common Lisp 中,您可以使用 alexandria:shuffle 对广义序列执行相同的任务,而 clojure 中的等效函数是 clojure.core/shuffle。

    循环构造

    有一个名为 clj-iter 的库,其灵感来自 CL 的 iterate 函数,该函数本身基于 loop。但是,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 的一种高效实现。

    【讨论】:

    • 这只是loop 的样本,不多也不少。
    • @GoloRoden 我很难理解您评论背后的信息。您的意思是当前措辞的答案缺少您问题的某些方面吗?我仍然可以编辑问题。如果这是关于洗牌算法的,我只是觉得这对于可能偶然发现您的问题的其他人来说很有趣。
    猜你喜欢
    • 2012-05-20
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    相关资源
    最近更新 更多