可以安全地忽略宏和内置之间的区别吗?

Jim*_*imB 7 lisp macros clojure

我开始使用Clojure,这也是我的第一个口齿不清.显然有很多东西需要考虑,为了减轻认知负担,我试图找到我可以安全忽略的部分(现在).

可以安全地处理带有内置插件的宏和表单的表单,或者是否会出现以后会出现的陷阱?

换句话说,我是否会遇到需要知道(defn f1 [])扩展的情况

(def f1 (.withMeta (clojure.core/fn f1 ([])) (.meta (var f1))))
Run Code Online (Sandbox Code Playgroud)

Art*_*ldt 9

宏通常构成非常不同.宏不是"一等公民":你不能将它们传递给map等等,你不能将它们存储在变量中,你不能将apply它们列入参数列表.最初你不需要担心这些因为它们显然不会起作用:一个微妙的,难以察觉的错误将会更加令人不安.如果你试图跑

(map if [true false true false] [1 2 3 4] [-1 -2 -3 -4])
Run Code Online (Sandbox Code Playgroud)

事实上,如果不是一个功能将变得非常明显.请记住,宏不是函数,你应该没问题:)

PS:宏是 (fn (fn (fn :-D) :^P) :O)

  • 这似乎解决了OP关注的问题:你在(a)宏和特殊形式以及(b)功能之间做了区分.无论是特殊形式还是宏都不能作为参数传递给像map这样的高阶函数; 他在询问是否有任何特殊形式与宏有意义地不同的方式. (3认同)

ama*_*loy 7

在几乎所有情况下,您都可以完全忽略这种区别.(实际上你有,因为fn不是内置的 - 它是一个扩展到fn*的宏)

我遇到的唯一例外是,如果您尝试重新定义它们,宏和内置函数的行为会有所不同.只是不要重新定义任何现有的功能,你会很好地对待它们.