Clojure循环形式如何工作?

Amo*_*kar 3 clojure

我是Clojure和功能编程的新手.我尽我所能,理解循环结构.

我可以使用它,我可以查看用它编写的代码并告诉输出但我不明白的是,它是如何工作的?

是否与使用参数编写匿名函数然后使用相同的arity和new值保持重复?

它是一个内置的宏还是它的东西?

dby*_*rne 7

实际上,loop不是函数或宏.这是一种特殊的形式.它的作用就像let(它也是一种特殊的形式),除了它作为一个目标recur.

区分函数,宏和特殊形式的一种方法是检查其参数的计算方式:

  • 始终计算函数参数,然后将结果传递给函数.
  • 在宏扩展为新的未评估表单之前,不会评估宏参数.
  • 传递时不评估特殊形式参数,但特殊形式可能会或可能不会选择在内部对它们进行评估.


ama*_*loy 5

dbyrne的答案都是正确的,而且很好,但是我想解决你的进一步问题"它是否与编写带参数的匿名函数相同,然后recur在尾部具有相同的arity和new值?".是的,它完全是这样的:

(loop [x 1, y 2]
  (if (whatever x y)
    (recur (inc x) (dec y))
    (* x y)))
Run Code Online (Sandbox Code Playgroud)

在功能上是相同的

((fn [x y]
   (if (whatever x y)
     (recur (inc x) (dec y))
     (* x y)))
 1 2)
Run Code Online (Sandbox Code Playgroud)

如果loop不存在,您可以将其编写为发出此类形式的简单宏,但编译器具有loop更快的特殊形式.

(defmacro loop [bindings & body]
  (let [bindings (partition 2 bindings)]
    `((fn [~@(map first bindings)]
        (do ~@body))
      ~@(map second bindings))))
Run Code Online (Sandbox Code Playgroud)