James Long has an interesting post up at his blog entitled Lisp: It’s Not About Macros, It’s About Read in which he argues that what makes Lisp so powerful is not really macros but the read function. The reason for this is that read
is really a parser that converts an input stream into Lisp objects. For example in
ELISP> (read "(+ x 1)")
(+ x 1)
read
takes the string "(+ x 1)"
and turns it into the Lisp S-expression (+ x 1)
. That may seen like a distinction without a difference but consider
ELISP> (car (read "(+ x 1)"))
+
This is another example of code equaling data that we’ve discussed here so often. We’ve taken a piece of data, "(+ x 1)"
, and turned it into a bit of Lisp code.
Here’s a more substantive example taken from Long’s post and converted from Scheme to Elisp. Consider the two line function
(defun parse-defun (forms) (list 'fset (cons 'quote (list (cadr forms))) (cons 'lambda (cons (caddr forms) (cdddr forms)))))
When we apply it to a defun
expression
ELISP> (parse-defun (read "(defun add1 (x) (+ x 1))")) (fset 'add1 (lambda (x) (+ x 1)))
we get the Elisp code to make a function. Note that parse-defun
will work with any function defined with defun
. We haven’t merely rearranged some text here. It’s much more:
ELISP> (eval (parse-defun (read "(defun add1 (x) (+ x 1))"))) (lambda (x) (+ x 1)) ELISP> (add1 3) 4
When we evaluate the code from parse-defun
we really do get a function. That’s pretty impressive for the amount of work that we did. If you’re not impressed, ask yourself if you could (easily) do this in C, or Python, or Ruby, or whatever your favorite non-Lisp language is.
Long says that the real power of macros is that they allow us to install functions like parse-defun
into the Lisp compiler. When the compiler reads a macro name it passes the forms to the function that the macro represents and then processes its output. That’s a rather obvious point once someone points it out but I think it’s a profound one that helps place macros in their proper place in the Lisp universe.
If this stuff excites you, as it does me, be sure to head over to Long’s blog and read his post. You won’t be sorry.