Clojure 为什么不计算函数的返回值,而计算宏的返回值?

Clojure 为什么不计算函数的返回值,而计算宏的返回值?,clojure,Clojure,添加一个和一个的函数: (定义一加一[](列表+1)) 调用时返回: (#object[clojure.core$_PLUS_u0x47fa7bd5“clojure.core$uu PLUS_@47fa7bd5”]11) 包装在宏中的相同函数体: (一加一[](列表+1)) 调用时返回: 2 为什么Clojure希望宏返回可以计算的表达式 编辑 对的回答说明了宏与函数的区别。但没有回答为什么。打个比方,我知道一个物体从某个高度落下,垂直落在地上。我的问题是为什么它垂直下降 让我们从一件事开始,许

添加一个和一个的函数:

(定义一加一[](列表+1))

调用时返回:

(#object[clojure.core$_PLUS_u0x47fa7bd5“clojure.core$uu PLUS_@47fa7bd5”]11)

包装在宏中的相同函数体:

(一加一[](列表+1))

调用时返回:

2


为什么Clojure希望宏返回可以计算的表达式

编辑


对的回答说明了宏与函数的区别。但没有回答为什么。打个比方,我知道一个物体从某个高度落下,垂直落在地上。我的问题是为什么它垂直下降

让我们从一件事开始,许多人都非常清楚,他们在解释宏时忘记了明确地考虑它,这会导致其他人在学习思考宏时感到困惑:


-------->宏是可能重复的函数,我想您应该阅读更多有关宏的内容。可以将宏调用视为在编译时用宏的内容替换自身的代码。因此,对于宏一加一,您可以想象
(一加一)
(+11)
放入源代码,然后将其与其他源代码一起计算。重新编辑并引用函数,转换值,宏将代码转换为其他代码。您的函数示例只是返回一个列表结构,这就是你定义它要做的。宏将展开为代码
(+1 1)
,对该代码求值时,结果为2。通过运行
(macroexpand'(一加一))
“Clojure为什么希望宏返回可以计算的表达式?”可以看到中间层,因为这就是拥有宏的意义所在。你的问题听起来像是在问“为什么宏的行为像宏?”我想你真的是想问Sam Estep提到的一个问题,所有这些都是关于值得怀疑的合理问题。我一直在运用类似的思维过程来理解宏。在REPL进程中,宏位于Read和Eval之间。这就是为什么要计算宏的返回值,因为已经发生了“读取”。另一方面,对函数进行求值,并将其返回值提供给读取器。我可能错了。我还在想。再想一想,函数的返回值是要打印出来的,或者执行过程循环回来,返回值被输入到“读取”步骤。@ardsrk是的,你得到了。它循环回到读取阶段,如果第二次循环时它仍然是一个宏,那么第三次循环时它会再次循环。只要继续运行直到没有宏为止。然后,最终完全形成的代码实际上进入了完成的程序。你提出了一个有趣的观点。请详细说明您对第二次通行证的意见,并进一步说明。我在想,既然一个函数可以返回一个函数,它也可以返回一个宏……是的,这是正确的:如果它返回的表达式(通常是列表)是一个函数调用
(当…
,并且函数被标记为宏,那么它会再次循环。如果函数不是宏,则它停止循环并将其作为最终代码/表达式返回。宏是带有一些额外元数据的函数,这些元数据表示“我是宏”,这是使它们成为宏的唯一区别。运行
(meta#'clojure.core/when)
并查看
:宏