An example anaphoric macro in Common Lisp

Thu, Jul 2, 2015 2-minute read

Anaphoric macros are macros that capture symbols intentionally, only to refer to them by a different name (an apaphor is an expression referring to another.) A popular example in Common Lisp is the loop macro, which uses the symbol “it” to refer to certain things in different contexts. Here’s an example from wikipedia:

 (loop for element in '(nil 1 nil 2 nil nil 3 4 6)
       when element sum it)

As another example, here we will introduce a special version of the built-in “lambda” special form, that introduces a symbol “self” that refers to the lambda being defined. This allows one to write recursive lambdas with relative ease. First, the code:

(defmacro ref-lambda (params &body body)
  `(lambda ,params
     (labels ((self ,params ,@body))
       (self ,@params))))

In the lisp being returned, notice that we internally define a local function “self” via the “labels” construct. We splice in the parameter list and the body to execute. Lastly, we execute the the new local function “self” with the argument list spliced in. All this is wrapped in a lambda function, so we can still embed code using this directly into the call-site with no indication of any foul play.

As an example, here’s a totally anonymous recursive fibonacci calculation:

(funcall (ref-lambda (x)
           (cond ((= x 0) 1)
	         ((= x 1) 1)
		 (t (+ (self (- x 1))
		       (self (- x 2))))))
         5)

which gives us back 8.