【发布时间】:2017-10-13 21:33:36
【问题描述】:
我正在学习 Clojure 宏,想知道为什么我们不能只使用函数进行元编程。
据我所知,宏和函数之间的区别在于宏的参数不被评估,而是作为数据结构和符号传递,而返回值 被评估(在那个地方宏被调用的地方)。宏充当读取器和评估器之间的代理,在评估发生之前以任意方式转换表单。在内部,它们可以使用所有语言特性,包括函数、特殊形式、文字、递归、其他宏等。
功能正好相反。参数在调用之前进行评估,返回值不在返回之后。但是宏和函数的镜像特性让我想知道,我们是否也可以通过引用它们的参数(形式)、转换形式、在函数内部对其进行评估、最后返回来使用函数 as 宏这是价值。这在逻辑上不会产生相同的结果吗?当然这会很不方便,但理论上,每个可能的宏都有等效的功能?
这是简单的中缀宏
(defmacro infix
"translate infix notation to clojure form"
[form]
(list (second form) (first form) (last form)))
(infix (6 + 6)) ;-> 12
这是使用函数的相同逻辑
(defn infix-fn
"infix using a function"
[form]
((eval (second form)) (eval (first form)) (eval (last form))))
(infix-fn '(6 + 6)) ;-> 12
现在,这种看法是否适用于所有情况,或者是否存在一些宏观无法超越的极端情况?最后,宏只是函数调用的语法糖吗?
【问题讨论】:
-
请注意,宏在宏扩展时(通常在编译之前)而不是运行时递归扩展。编译后的代码就像您手动编写了展开式一样,因此没有性能损失。还要记住
eval在空词法环境中评估表单。(let [x 10] (infix-fn '(x + 6)))=>CompilerException ... Unable to resolve symbol: x -
这些都是我没想到的好点
标签: function clojure functional-programming macros lisp