Macros are useful to embedded some patterns.
For example, Common Lisp doesn't define the while
loop but has do
which can be used to define it.
Here is an example from
On Lisp.
(defmacro while (test &body body)
`(do ()
((not ,test))
,@body))
(let ((a 0))
(while (< a 10)
(princ (incf a))))
This will print "12345678910", and if you try to see what happens with
macroexpand-1
:
(macroexpand-1 '(while (< a 10) (princ (incf a))))
This will return:
(DO () ((NOT (< A 10))) (PRINC (INCF A)))
This is a simple macro, but as said before, they're usually used to
define new languages or DSLs, but from this simple example you can
already try to imagine what you can do with them.
The loop
macro is a good example of what macros can do.
(loop for i from 0 to 10
if (and (= (mod i 2) 0) i)
collect it)
=> (0 2 4 6 8 10)
(loop for i downfrom 10 to 0
with a = 2
collect (* a i))
=> (20 18 16 14 12 10 8 6 4 2 0)
Common Lisp has another kind of macros called reader macro which can
be used to modify how the reader interprets the code, i.e. you can
use them to use #{ and #} has delimiters like #( and #).