Macro for more than 1 line of code

这一生的挚爱 提交于 2019-12-13 13:32:01

问题


I'm learning the macro system of Common Lisp and suddenly found a problem

(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

Well. Why can't I generate 2 LoC from only one macro? How can I work around? (progn will not work in a more complicated situation...)


回答1:


Your macro needs to return just one form that will call both functions.
Instead you are generating two forms (and only the last one is used.)

Try:

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

or if you do not want to be limited to just 2 functions:

(defmacro call-funcs (&rest funcs)
  `(progn ,@(mapcar #'list funcs)))



回答2:


It didn't seem clear in the stuff above, so let me add... yes you can return 2 lines of code from a macro, but remember functions and macros generally only return 1 value. You can compute multiple values in function, but it only returns the last value. This function below only returns value-2 (it still computes value-1, it does nothing with value-1).

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

If you want to return 2 values you can either wrap them in a list (or other structure), or you can use #'values to return more than one value.

In this case, your macro can only return one statement, unless you wrap multiple values in a list or use #'values. What it returns has to be proper lisp code too, and usually that is done with a PROGN

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

If you used

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

Then your macro computes 2 values, but it only returns the last one. (as you see in your macroexpand above)

You can see this easily with a defun that computes 2 values but only returns the last one.

(defun myname () 1 2)

Using VALUES gets a little weird.

(defmacro tttt () '(values (one) (one)))
(tttt)
1
1


来源:https://stackoverflow.com/questions/14930091/macro-for-more-than-1-line-of-code

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!