Macros 如何调用宏并向其传递参数
看来我对宏的理解还不完整。 如何将参数传递给宏,并从函数调用它们。 代码下面看似简单的代码不起作用Macros 如何调用宏并向其传递参数,macros,clojure,lisp,Macros,Clojure,Lisp,看来我对宏的理解还不完整。 如何将参数传递给宏,并从函数调用它们。 代码下面看似简单的代码不起作用 (defmacro bar [arg] (println (symbol? arg))) (defn foo [arg] (bar arg)) (foo 'baz) => nil 宏应该生成代码。它将源表达式作为参数并创建新的源 你的宏采用什么源 宏生成的源是什么 让我们看看: user=> (defmacro bar [arg] (println (s
(defmacro bar [arg]
(println (symbol? arg)))
(defn foo [arg]
(bar arg))
(foo 'baz) => nil
宏应该生成代码。它将源表达式作为参数并创建新的源
user=> (defmacro bar [arg]
(println (symbol? arg)))
#'user/bar
user=> (bar 1)
false
nil
user=> (bar 'a)
false
nil
user=> (bar a)
true
nil
这是扩展:
user=> (macroexpand-1 '(bar a))
true
它不会生成任何有用的代码。定义foo时,将对宏进行求值。如果在repl中定义foo函数,您会注意到Clojure打印true
user=> (defmacro bar [arg]
(println (symbol? arg)))
#'user/bar
user=> (defn foo [arg]
(bar arg))
true ; <= This is the print from your macro
; (it prints true, because arg is a symbol)
#'user/foo
要使宏“工作”,它需要返回代码,通常作为列表表达式。因此,对于您的意图,您需要提供:
(defmacro bar (arg)
`(println (symbol? ,arg)))
(这将使用Quasikote作为构建列表的方便符号。)在使用bar
时,通过运行defmacro代码来扩展该用法,以生成该列表。然后对清单进行汇编。例如:
(progn (bar 10))
扩展为
(progn (println (symbol? 10))
编译后,运行代码并打印“nil”。您将注意到,(a条)
将产生一个错误“a未绑定”
”,因为扩展是(println(符号a))
,其中计算a
,可能没有值<代码>(条形图'a)返回T
使用此正确的bar
宏,您的函数foo
在编译时将扩展为:
(defun foo (x)
(println (symbol? x))
正确计算
(foo'a)
和(foo'10)
。如果我理解正确,那么foo的定义将扩展为(println(symbol?arg))将为(foo'baz)打印true。我这里缺少什么?@navgeet,不,您编写的宏不会扩展到(println(symbol?arg))
。宏只是一个函数,它必须返回展开形式。如果要获得所描述的内容,应该将宏的主体更改为类似于`(println(symbol?~arg))的内容。
(defun foo (x)
(println (symbol? x))