Clojure循环表单是如何工作的



我是Clojure和函数式编程的新手。我尽了最大的努力,理解了循环结构。

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

是否与写一个带参数的匿名函数相同,然后在尾部保留具有相同密度和新值的递归式?

是一个内置的宏还是什么?

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

区分函数、宏和特殊形式的一种方法是检查它们的参数是如何求值的:

  • 函数参数总是被求值,然后结果被传递给函数。
  • 在宏展开为新的未求值形式之前,不会计算宏参数。
  • 特殊表单参数在传递时不被求值,但是特殊表单可以选择也可以不选择在内部求值。

dbyrne的答案都是正确的,很好,但我想解决你的进一步问题"这是否等同于编写一个带有参数的匿名函数,然后在尾部以相同的密度和新值recur ?"。是的,就是这样:

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

最新更新