DEFMACRO
DEFMACRO
form defines a macro in global scope. It needs at least one symbol argument, which is not evaluated and will be the name of the macro. Second argument must be a list of parameters (symbols) of the macro, the symbols are not evaluated and will be used for local binding of parameters once the macro is called. Just like in DEFUN
, no parts of the DEFMACRO
expression are evaluated during the definition. Third argument is optional description string. If the third argument is not string, it is considered first form of the macro body. Any other parameters are to DEFMACRO
are stored as the macro body.
The syntax of DEFMACRO
is the same as DEFUN
, because the object created is a macro-expansion function - a function that produces code. The difference between function and macro only takes effect when the macro or function is called. Arguments to macro call are not evaluated automatically, and they are supplied to the macro-expansion functions as forms. The macro itself takes control over the evaluation of the arguments. Output of the macro-expansion function should be code - a form that will be evaluated afterwards.
Function and macro names are in the same namespace. When defining macro with the same name as existing function, LabLISP will just inform the user, the previous function definition will be dropped and the symbol will refer to macro.
As example we define macro for adding, just as trivial as in the example for DEFUN
>(defmacro adder (a b) ; macro named ADDER, arguments A, B “replaces plus” ; optional description string `(+ ,a ,b)) ; quoted form, unquoted A, B ADDER ; DEFMACRO returns the symbol naming the new macro
When called, we just receive the expected result:
>(adder 1 3) 4
What happens during the call is that the arguments 1 and 3 were supplied to the macro-expansion function, which produced a list (+ 1 3)
, using the BACKQUOTE
and UNQUOTE
operators. Only after, this list is evaluated as form, and gives the result.
In the following example, we call the macro with the forms (- 2 1)
and (+ 2 1)
as parameters. The macro code will receive the forms, not the results of those, as would be the case in function call.
>(adder (- 2 1) (+ 2 1)) 4
In the macro-expansion function, the UNQUOTE
operations evaluate the symbols A
and B
as the forms (- 2 1)
and (+ 2 1)
, so the expansion function produces code (+ (- 2 1) (+ 2 1))
and that is evaluated at the end.
One can inspect the result of macro-expansion functions with MACRO-EXPAND
:
>(macro-expand '(adder (- 2 1) (+ 2 1))) ; supply quoted code to MACRO-EXPAND function (+ (- 2 1) (+ 2 1)) ; result of the expansion
Optional parameters
Analogically to functions, the parameter list of DEFMACRO
can have &OPTIONAL
and &REST
parameters (see DEFUN
). In DEFMACRO
it is possible to use &WHOLE
parameter as first parameter, before any mandatory paramters. The &WHOLE
parameter is not counted to the number of parameters, and will be bound to the whole list of supplied arguments, when the macro is called.
Following example defines macro for 2 arguments:
>(defmacro bar (&whole c a b) `(progn (print ',c) (+ ,a ,b))) BAR USER>(bar 2 3) (2 3) ; the whole list of arguments is printed 5
In DEFMACRO
, the keyword &BODY
can be used instead of &REST
, but they have exactly the same meaning in LabLISP.
See also: MACRO-EXPAND
, MACROLET
, SYMBOL-MACROLET