"until" loop - My first elisp macro
Published on Dec 19, 2021, by Junji Zhi
Recently I was reading On Lisp by Paul Graham and got interested in using macros in Emacs Lisp. I decided to play with it.
Here’s my first macro: a until
loop:
(defmacro until (test &rest body)
`(while (not ,test)
,@body))
Think of until
as a negative while
. The loop runs until the test becomes true.
To use it:
(setq jz/counter 1)
(setq jz/res '())
(until (>= jz/counter 5)
(setq jz/counter (+ 1 jz/counter))
(setq jz/res (cons jz/counter jz/res)))
;; jz/res => (5 4 3 2)
One note about defining macros: If we want to splice the rest of the lisp statement, we need two things:
- Add a
&rest
in the macro argument List. It means that there are arbitrary number of statements there, and we wrap them all intobody
. - use comma-at, or
,@
to splice thebody
. It is similar to the spread operator...
in Javascript ES6 that can unwrap an object into another.
I’m not sure whether this is the most efficient way to define macros. But it definitely kicks off an interesting adventure!