An Emacs Lisp rosetta for Clojurians

..

This document is aimed at Clojure programmers who want to learn some Emacs Lisp.

As of 2022-09-10, it’s nowhere near complete. And it probably never will be.

Here’s a better rosetta: https://hyperpolyglot.org/lisp. In addition to Clojure and Emacs Lisp, it includes Common Lisp and Racket.

Loop for side effects

In Clojure, map and for are intended for iterating over pure functions. They are lazy, and may never finish.

For side-effectful code, doseq is my goto.

Here’s how we can print some numbers:

(doseq [n (range 3)]
  (println (str  n "? No!!!")
           "You are not a number! You are a free man!"))
0? No!!! You are not a number! You are a free man!
1? No!!! You are not a number! You are a free man!
2? No!!! You are not a number! You are a free man!

Now, let’s print to *Messages* in Emacs Lisp. We can use the cl-loop macro. I don’t care too much about idiomatic solutions now — I want to get something working first.

Here is the example from the docs:

(cl-loop for i from 1 to 5
         collect i)

Now, let’s try make that print into *Messages*:

(cl-loop for i from 1 to 5
         (progn (message i)))

Nope, that doesn’t work.

Reading the docs again, it looks like cl-loop supports a do EXPRS... clause. Let’s give that a shot.

(cl-loop for i from 1 to 3
         do (message (string i)))

Woah, that printed

^A
^B
^C

.

I had no idea how to use the built in docs to look this up, so I ended up searching for “emacs lisp convert int to string”. And I found number-to-string.

(number-to-string 123)
123

So! Let’s try again.

(cl-loop for i from 1 to 3
         do (message (number-to-string i)))
1
2
3

Nice!

To insert into a buffer, we can replace message with insert.

(defun teod-temp-insert-lines-123 ()
  (interactive)
  (cl-loop for i from 1 to 3
           do (insert (number-to-string i) "\n")))

Now we can use that function to insert some lines with M-x teod-temp-insert-lines-123.

1
2
3

😊

And I can write the function I really wanted!!!

(defun teod/insert-empty-lines-in-org-mode ()
  (interactive)
  (insert "#+BEGIN_VERSE")
  (cl-loop for i from 1 to 15
           do (insert "\n"))
  (insert "#+END_VERSE"))

Yay!

When writing org-mode documents that I export to HTML, I often like to have a preview without having to scroll the web browser all the time. Adding about half a page height solves this nicely. Sure, I could do it with CSS. But I’d rather just have a simple Org-mode document.