Clojure循环形式如何工作?

时间:2013-04-08 18:34:57

标签: clojure

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

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

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

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

2 个答案:

答案 0 :(得分:7)

实际上,loop不是函数或宏。这是一个special form。它就像let(也是一种特殊形式)一样工作,但它充当recur的目标。

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

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

答案 1 :(得分:5)

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

(loop [x 1, y 2]
  (if (whatever x y)
    (recur (inc x) (dec y))
    (* x y)))

在功能上与

相同
((fn [x y]
   (if (whatever x y)
     (recur (inc x) (dec y))
     (* x y)))
 1 2)

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

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