Reputation: 590
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...)
Upvotes: 4
Views: 274
Reputation: 583
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
Upvotes: 0
Reputation: 48619
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)))
Upvotes: 10