A brief explanation of what lisp macros are

A lisp program looks something like this:

(a b c d)
(m o (p k))
(a b c (d e f g (h i j k) l m) 
       n 
       (o p q (r s t (u v) (w x y)) 
           z))

The only form of syntax in lisp is the (a b c ..) form.

The if statement looks like this:

(if a b)

A function call also looks like this:

(foo a b)

A function definition looks sorta like this:

(def foo (a b) body)

Contrast this with python, where the if statement is of the form:

if a: b

And if ‘b’ is multiple lines:

if a:
    b

And the function call is of the form:

foo(a, b)

And the function definition is like:

def foo(a, b):
     body

Without delving too deep into “how”, you can now know what macros do.

Macros are a way of defining new forms of statements.

(bar a b c)

It looks exactly like all other forms of statements.

Why would you define a new form of statements? To abstract the syntax away. To get rid of repetitive code that you can’t get rid of using functions or even higher order functions.

For example:

if some_expression(a, b, c):
      do_something_with( some_expression(a, b, c), d, e, f)
      another_thing(some_expression(a, b, c))

Notice we’re repeating the expression some_expression(a, b, c) and not only that, but we’re calling the function twice.

It’s better to:

x = some_expression(a, b, c)
if x:
    do_something(x, d, e, f)
    another_thing(x)

This is a pattern that can repeat itself in many places.

Some languages allow you to:

if x = some_expression(a, b, c):
   use(x)
   again(x)

But if the language doesn’t provide such a syntax, you can’t define it yourself.

Lisp macros basically allow you to define a new type of statement that 1) look like the rest of the language 2) doesn’t have to wait for the language makers to implement them.

Another good example, the pattern:

try:
    statement block
catch:
    do nothing

In lisp, you can define a macro for that:

(errsafe expression)

Note that an expression can be a statement block.

This is actually the name of an Arc macro, but there’s nothing special about how arc defines it, it’s just like how you can define a function in C; if the standard library doesn’t come with it, you can just write it yourself.

Notes

  1. hasenj-dev posted this