Skip to content

Instantly share code, notes, and snippets.

@frankpf
Last active December 21, 2017 22:40
Show Gist options
  • Save frankpf/6481a3bfd9cb5c735c80 to your computer and use it in GitHub Desktop.
Save frankpf/6481a3bfd9cb5c735c80 to your computer and use it in GitHub Desktop.

Lisp macros

An example from Practical Common Lisp

Some fundamental notions

Lisp has a very simple syntax:

(<function> ...)

A function in Lisp has the following form:

(defun <function-name> (<parameter1> <parameter 2> ...)
  <body>)

Here's an example:

(defun sum-of-two-numbers (x y)
  (+ x y))

This is a function named sum-of-two-numbers with two parameters, x and y. The body is (+ x y) which means x + y. In a defun, the value of the last expression evaluated is returned. Therefore, this function returns the result of evaluating (+ x y).

The last thing you need to know is the quote macro (more on macros later). Everything in Lisp is a list and can be manipulated, but sometimes you don't want that list to be evaluated.

Say you want to define a variable with a list of fruits:

(defvar fruits (banana apple orange))

This won't work for a simple reason. The interpreter will first try to apply a function named banana to the arguments apple and orange. Since there is no banana function (and the arguments apple and orange are not defined variables either), this will throw an error.

What you actually want to do is store the (banana apple orange) list in the fruits variable, without evaluating (banana apple orange). quote helps us here:

(defvar fruits (quote (banana apple orange)))

This is used a lot, so there's some syntatic sugar for it:

(defvar fruits '(banana apple orange))

A taste of macros

When Lisp sees a macro, it passes the arguments to the macro body WITHOUT evaluating them. That returns a new Lisp expression that is then evaluated instead of the original macro.

Here's a simple example. reverse is a function that takes a list as an argument and returns the list reversed. So this:

(reverse '(1 2 3))

evaluates to this:

(3 2 1)

Now let's define a macro using reverse:

(defmacro backwards (expression)
  (reverse expression))

TODO: Explain why this is awesome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment