我正在学习Common Lisp的宏系统,突然发现了一个问题
(defun hello () (format t "hello ~%"))
(defun world () (format t "world ~%"))
(defmacro call-2-func (func1 func2)
`(,func1)
`(,func2))
(macroexpand-1 '(call-2-func hello world))
(WORLD)
T
好。为什么我不能只从一个宏生成2个LoC?我该如何解决? ( progn将无法在更复杂的情况下工作...... )
答案 0 :(得分:9)
您的宏只需返回一个表单,该表单将调用这两个函数 而是生成两种形式(并且只使用最后一种形式。)
尝试:
(defmacro call-2-func (func1 func2)
`(progn (,func1) (,func2)))
或者如果您不想仅限于2个功能:
(defmacro call-funcs (&rest funcs)
`(progn ,@(mapcar #'list funcs)))
答案 1 :(得分:0)
在上面的内容中似乎并不清楚,所以让我添加...是的,您可以从宏返回2行代码,但记住函数和宏通常只返回1个值。您可以在函数中计算多个值,但它只返回最后一个值。下面的这个函数只返回值-2(它仍然计算值-1,它对值-1没有任何作用)。
(defun myfun () (compute-value-1) (compute-value-2))
如果要返回2个值,可以将它们包装在列表(或其他结构)中,也可以使用#'值返回多个值。
在这种情况下,除非在列表中包装多个值或使用#'值,否则宏只能返回一个语句。它返回的内容也必须是正确的lisp代码,通常用PROGN
完成(defmacro call-2-func (func1 func2) `(PROGN (,func1) (,func2)))
如果您使用
(defmacro call-2-func (func1 func2) `(,func1) `(,func2))
然后你的宏计算2个值,但它只返回最后一个。 (正如您在上面的宏扩展中看到的那样)
你可以通过一个defun来轻松地看到这个,它可以计算2个值但只返回最后一个值。
(defun myname () 1 2)
使用VALUES会有点奇怪。
(defmacro tttt () '(values (one) (one)))
(tttt)
1
1