4

正在学习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 不会在更复杂的情况下工作......)

4

2 回答 2

9

您的宏只需要返回一种可以调用这两个函数的形式。
相反,您正在生成两种形式(并且只使用最后一种。)

尝试:

(defmacro call-2-func (func1 func2)
  `(progn (,func1) (,func2)))

或者,如果您不想仅限于 2 个功能:

(defmacro call-funcs (&rest funcs)
  `(progn ,@(mapcar #'list funcs)))
于 2013-02-18T05:58:05.133 回答
0

上面的内容似乎不太清楚,所以让我补充一下……是的,您可以从宏中返回 2 行代码,但请记住函数和宏通常只返回 1 个值。您可以在函数中计算多个值,但它只返回最后一个值。下面的这个函数只返回 value-2(它仍然计算 value-1,它对 value-1 不做任何事情)。

(defun myfun () (compute-value-1) (compute-value-2))

如果要返回 2 个值,可以将它们包装在列表(或其他结构)中,也可以使用 #'values 返回多个值。

在这种情况下,您的宏只能返回一个语句,除非您将多个值包装在一个列表中或使用 #'values。它返回的内容也必须是正确的 lisp 代码,并且通常使用 PROGN

(defmacro call-2-func (func1 func2) `(PROGN (,func1) (,func2)))

如果你用过

(defmacro call-2-func (func1 func2) `(,func1) `(,func2))

然后你的宏计算 2 个值,但它只返回最后一个。(如您在上面的宏扩展中看到的)

您可以使用计算 2 个值但只返回最后一个值的 defun 轻松看到这一点。

(defun myname () 1 2)

使用 VALUES 有点奇怪。

(defmacro tttt () '(values (one) (one)))
(tttt)
1
1
于 2013-07-04T17:08:22.157 回答