Idiomatic Macros for Common Lisp

Every programming language has idioms–patterns used so frequently that they are almost considered part of the language itself. (See these C idioms for examples.) Common Lisp, with almost unlimited possibilities for syntax, depends more heavily on idioms to remain comprehensible. Some examples are defsomething or define-something for definitions, something-p for predicate tests, and make-something for constructors.

Marco Antoniotti created a clever macro package called DEFINER that codifies the most common of these, definitions, into a single macro with consistent syntax for any object that is being defined. With DEFINER, all definitions can be made with a single macro: def, which is followed by a symbol specifying what is being defined. So defun becomes def function, defvar becomes def var, and define-condition becomes def condition.

Of course, this is Lisp, so def can be turned on itself to produce new definition forms with def definer. New def forms can then be created that follow the same syntactic pattern of:

(def type-of-thing name properties...)

As Marco writes, DEFINER “makes it possible to homogeneize a natural programming practice followed by several CL programmers.”

I say, why not extend this practice to other idioms? Here’s a list of other Common Lisp idioms I think could be well-served by the same sort of homogeneization:

with
Use with thing to delimit the scope of certain things–local variables, special variables, functions, open files, etc. Then let becomes with lexicals, labels becomes with functions, and with-open-file becomes with file.
make
A generic constructor for any anonymous (unnamed) object. This could ensure that all object constructors follow a predictable pattern after make instance, and turns lambda into the infinitely more readable make function. Also begs the question of why one can’t create anonymous classes.
is
A generic predicate, borrowed from the FiveAM testing framework. Should alway return a boolean true/false value. Gives us the more readable is even instead of evenp.
equal
Replace Lisp’s scattering of equality predicates–eq, eql, equal, equalp, =, string=, etc.–with forms like equal object, equal contents, equal number, and equal string. One could alternately use is equal, although that looks odd in English grammar.
as
A generic type converter. Makes it more obvious, for example, when string is being used as a type specifier and when as a coercion function. Also makes it very easy to define new converters between types, assuming these are implemented as generic functions.
get
Generic accessor. Replaces both primitives like car as well as object-related functions like slot-value.
set
Replacement for setf. Every get form should have a corresponding set. Primitives like rplacd become set cdr.

And of course, to top it off we would want def with, def maker, def is, def equality, and def as. And while we’re at it, def idiom!

The point of all this is to make code more readable. One can reduce the 978 Common Lisp symbols to pairs of symbols, the first naming the general category of operation and the second specifying the exact operation within that category.

When examining unfamiliar code that uses these idiomatic macros, a programmer can look at the categorical names to get a rough idea of what is happening even without knowing about the specific functions being used. This can make Common Lisp more manageable without sacrificing any of its expressiveness.

One Reply to “Idiomatic Macros for Common Lisp”

  1. I’m new to Lisp, well kinda anyway, and I couldn’t agree with you more. The lack of generality in certain areas of Common Lisp is the only thing that has bothered me, might just be me not being used to Common Lisp. I hope that someone will make this possible, or maybe I will be able to do it when I know Common Lisp a little better. Awsome post!

Comments are closed.