我正在学习Clojure宏,想知道为什么我们不能只使用函数进行元编程。
据我所知,宏和函数的区别在于宏的参数不会被评估,而是作为数据结构和符号传递,返回值在调用宏的地方被评估。宏在阅读器和求值器之间充当代理,可以以任意方式转换形式,然后执行评估。它们可能在内部使用所有语言特性,包括函数、特殊形式、文字、递归、其他宏等。
函数则相反,调用前先对参数进行评估,但在返回时不进行评估。但宏和函数的映射关系让我想知道,难道我们不能使用将函数引用(即形)作为参数,转换形式,在函数内部进行评估,最后返回其值的函数作为宏吗?这是否会在逻辑上产生相同的结果?当然,这样做很不方便,但从理论上讲,每个可能的宏都有一个等效的函数吗?
下面是一个简单的中缀宏。
据我所知,宏和函数的区别在于宏的参数不会被评估,而是作为数据结构和符号传递,返回值在调用宏的地方被评估。宏在阅读器和求值器之间充当代理,可以以任意方式转换形式,然后执行评估。它们可能在内部使用所有语言特性,包括函数、特殊形式、文字、递归、其他宏等。
函数则相反,调用前先对参数进行评估,但在返回时不进行评估。但宏和函数的映射关系让我想知道,难道我们不能使用将函数引用(即形)作为参数,转换形式,在函数内部进行评估,最后返回其值的函数作为宏吗?这是否会在逻辑上产生相同的结果?当然,这样做很不方便,但从理论上讲,每个可能的宏都有一个等效的函数吗?
下面是一个简单的中缀宏。
(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
- jkiiski