2015-02-21 Lorem ipsum dolor sit Emacs

As many LaTeX users know, sometimes you just need some dummy text so that you can test a font, a layout or something like that. In such cases, the lipsum package (or kantlipsum, if you’re feeling philosophical) is really handy. OTOH, when coding things like Org-mode exporters, a similar thing for Emacs’ Org-mode would be also useful. So I decided to write lipsum.el.

Well, but I didn’t write it after all. I googled first, and it turns out that I was late by more than a decade… Here it is on GitHub: https://github.com/jschaf/emacs-lorem-ipsum. It is not exactly idiomatic Elisp (I’ll come back to this in a moment), and it uses randomization, so I might write my own version some day (LaTeX’s lipsum is fully deterministic, and I prefer that to random sentences each time), but it’s here and it works.

Coming back to the “idiomatic Elisp” part. Don’t get me wrong, I’m not trying to claim that I’m an expert Elisp programmer – I’m not. But while we’re at it, why not study a piece of code from that package, just in case some beginner reads this? So, here it is:

(defun lorem-ipsum-insert-paragraphs (&optional num)
  "Insert lorem ipsum paragraphs into buffer.
If NUM is non-nil, insert NUM paragraphs."
  (interactive "p")
  (if (not num)(setq num 1))
  (if (> num 0)
      (progn
	(insert (concat
		 (mapconcat 'identity
			    (nth (random (length lorem-ipsum-text))
				 lorem-ipsum-text)
			    lorem-ipsum-sentence-separator)
		 lorem-ipsum-paragraph-separator))
	(lorem-ipsum-insert-paragraphs (- num 1)))))

First of all, I really don’t like the (if (not num)(setq num 1)) part; I believe that the common idiom would be to write (setq num (or num 1)).

Then, while I appreciate the mathematical elegance of tail recursion, the bad news is that Elisp is not Scheme, and you can easily run out of stack. (Here’s a trivial way to check this: define

(defun tail-recursion-test (n)
  (when (> n 0)
    (insert (format "Countdown: %s\n" n))
    (tail-recursion-test (1- n))))

and run it with a large parameter.) While that might not be considered Lispy enough, I guess that a simple dotimes would do better here.

Yet another problem I have with this code is the

(if (...)
    (progn ...
           ...))

construct. It is exactly the situation when when should be used – there is no “else” branch, and the “then” branch consists of more than one expression.

Last but not least: while (- num 1) is perfectly fine, I personally would use (1- num) – though I can imagine that someone might prefer the longer version for its ostensible readability.

Anyway: again, this all is not to say that someone did a poor job. All these “problems” are in fact minor ones. It’s just that the (good enough, but arguably not optimal) code is an opportunity to learn.

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode, CategoryTeX