Lisp - Code Generation Using Macros
In LISP, macros is a powerful tool to extend language capability by writing a code which can generate code. Macros allows metaprogramming in LISP. In this chapter, we'll explore multiple examples of macros used in code generation.
Example - Create a Square Function using Macro
main.lisp
; define a macro accepting x and returns square of it (defmacro my-square (x) `(* ,x ,x)) ; (my-square 5) expands to (* 5 5) (print (my-square 5)) (terpri) ; (my-square (+ 2 3)) expands to (* (+ 2 3)(+ 2 3)) (print (my-square (+ 2 3)))
Output
When you execute the code, it returns the following result −
25 25
Explanation
defmacro my-square (x) − macro my-square is defined using defmacro with an argument x
`(* ,x ,x) − a template is created using backquote and using comma, value of x will be inserted in the template
(my-square 5) − expression is expanded (* 5 5) and is evaluated as 25.
Example - Create a Loop using Macro
main.lisp
; define a macro to create a loop
(defmacro my-loop (var start end body)
`(do ((,var ,start (+ ,var 1)))
((> ,var ,end))
,body))
; call loop to print 1 to 5
(my-loop i 1 5 (print i))
Output
When you execute the code, it returns the following result −
1 2 3 4 5
Explanation
defmacro my-loop − macro my-loop is defined using defmacro with an arguments to define a loop.
`(...) − a template is created using backquote and using do construct, a loop is run.
,... − comma is used to insert values in the template.
Example - Create a Loop using Macro
main.lisp
; define a macro to create a loop
(defmacro my-loop (var start end body)
`(do ((,var ,start (+ ,var 1)))
((> ,var ,end))
,body))
; call loop to print 1 to 5
(my-loop i 1 5 (print i))
Output
When you execute the code, it returns the following result −
1 2 3 4 5
Explanation
defmacro my-loop − macro my-loop is defined using defmacro with an arguments to define a loop.
(var start end body)− four parameters are passed, a loop variable, start value, end value and body of the loop.
`(...) − a template is created using backquote and using do construct, a loop is run.
,... − comma is used to insert values in the template.
Example - Create a Function using Macro
main.lisp
; define a macro to define a function
(defmacro def-my-function (name params &body body)
`(defun ,name ,params
,@body))
; define the function add-two-numbers using macro
(def-my-function add-two-numbers (x y)
(+ x y))
; prints 7
(print (add-two-numbers 3 4))
Output
When you execute the code, it returns the following result −
7
Explanation
defmacro def-my-function − macro def-my-function is defined using defmacro with an arguments to define a function.
(name params &body body)− three parameters are passed, a function name, parameters to be pased and body of the function.
`(...) − a template is created using backquote and using do construct, a loop is run.
,... − comma is used to insert values in the template.
,@body − comma-at is used to insert body of the function.
def-my-function − macro is used to define a function by passing name of the function, parameters to be passed and a body.