For some reason it makes my teeth hurt to have my macros generate code that I wouldn’t have written by hand. For example it’s not hard to get code like this out of a macro expansion.

(let () (progn (if (fp x) (progn (f1 x) (f2 x)))))

v.s. what I might like:

(when (fp x) (f1 x) (f2 x))

I probably ought to just relax and ignore it, but instead I often revise macros so the code they generate is nicer to look at. So that:

`(let ,vars ,@body)

becomes

(if vars `(let ,vars ,@body) `(progn ,@body))

This is silly! Now I have ugly macros instead of ugly output. I’m just moving the ugly bits around.

So I’ve started doing this:

(tidy-expression `(let ,vars ,@body))

where tidy-expression is something like this:

(defun tidy-expression (x) (match x (`(or ,a (or ,@b)) `(or ,a ,@b)) (`(progn ,a (progn ,@b)) `(progn ,a ,@b)) (`(progn ,x) x) (`(and ,a (and ,@b)) `(and ,a ,@b)) (`(if ,a (progn ,@b)) `(when ,a ,@b)) (`(if ,a (progn ,@b) (progn ,@c)) `(cond (,a ,@b) (t ,@c))) (`(if ,a (progn ,@b) ,c) `(cond (,a ,@b) (t ,c))) (`(if ,a ,b (progn ,@c)) `(cond (,a ,b) (t ,@c))) (`(let ,vs (progn ,@body)) (tidy-expression `(let ,vs ,@body))) (`(let nil ,@body) (tidy-expression `(progn ,@body))) (_ x)))

It’s another chapter in my crush on optima.

I write these tidy up functions as necessary.

That example only chews on the top of the form. If you wanted something to clean up the first example you’d need to write tidy-expression-all.

(tidy-expression-all '(progn (if (fp x) (progn (f1 x) (f2 x))))) --> (when (fp x) (f1 x) (f2 x))

This all reminds me of Warren Teitelman’s programmer’s assistant in Interlisp. It reminds me of some of the things that flycheck in Emacs does for other programming languages. It reminds me that I’ve been wondering what would a lint for Common Lisp would look like.

I bet somebody already wrote a generalized tidy expression and I just don’t know were to look.