我开始使用Clojure,这也是我的第一个口齿不清。显然有很多东西需要考虑,为了减轻认知负担,我试图找到我可以放心忽略的部分(现在)。
可以安全地处理带有内置插件的宏和表单相同的表单,还是会出现以后会出现的陷阱?
换句话说,我是否会遇到需要知道(defn f1 [])
扩展到
(def f1 (.withMeta (clojure.core/fn f1 ([])) (.meta (var f1))))
答案 0 :(得分:9)
一般来说,宏的构成方式非常不同。宏不是“一等公民”:你不能将它们传递给map
等,你不能将它们存储在变量中,你不能将它们apply
变成一个参数列表。最初你不需要担心这些,因为它们显然不起作用:一个微妙的,难以检测的错误会更令人不安。如果你试图运行
(map if [true false true false] [1 2 3 4] [-1 -2 -3 -4])
if 不是函数的事实将变得非常明显。请记住,宏不是函数,你应该没问题:)
PS:宏是(fn (fn (fn :-D) :^P) :O)
答案 1 :(得分:7)
几乎在所有情况下,您都可以完全忽略这种区别。 (实际上你有,因为fn不是内置的 - 它是一个扩展到fn *的宏)
我遇到的唯一例外是,如果您尝试重新定义它们,宏和内置函数的行为会有所不同。只是不要重新定义任何现有的功能,你可以很好地对待它们。
答案 2 :(得分:1)
我自己就是一个Clojure新手,但还有一点时间尝试这种语言。
我可以说Clojure内置宏非常安全,因为你可以在不知道它们是宏的情况下使用它们。
特别是,因为Clojure比Common Lisp更注重不变性,所以你很难陷入由行为不端的宏引起的错误。
所以,不,你不会遇到需要了解内置宏内部的情况。但是如果你想弄清楚你自己的自定义宏的内部,那么总是macroexpand。