random-state.net

Nikodemus Siivola

<< next | top | previous >>

Always use *earmuffs* #
hacking, November 14th 2010

I you're an old hand with Common Lisp, you can stop reading now. If on the other hand you occasionally find youself wondering: "When — and why — should I use *earmuffs* to name special variables?" do read on.

(I originally posted this as a comment here, but figured that maybe this deserves saying here too.)

You always want the earmuffs.

There's never any real excuse for leaving them out. The reason comes in two parts:

Case 1: binding a special variable by accident.

(defparameter foo "foo!")

(defun say-it ()
  (write-line foo))

(defun say-more (foo)
  (say-it)
  (format t "now say ~A~%" foo))

(say-more "bar!") will print out

say bar!
now say bar!

instead of the intended

say foo!
now say bar!

In this case the earmuffs tell you that binding the variable may alter behaviour globally.

Case 2: typo causing you to read a special instead of a local — but there's no warning.

Normally you get a compile-time warning and a run-time error for

(defun foo (bar)
  bat)

but if you've previously done

(defparameter bat "baseball")

then you don't get either, and will waste time debugging, trying to figure out where things go wrong.

If your code is for your personal enjoyment no-one cares if you use earmuffs or not, but when you post code or publish it, not marking *special* variables special will waste other people's time. Please don't do that.

Not just if your code has a bug: whenever I see

(defparameter no-earmuffs ...)

I realize I need to read the code extra-carefully because there's no guarantee that code that looks innocent at a glance will not have non-local side-effects or dependencies.

Always use the earmuffs. It's true that when you understand the rules you can break them, but for this one it is really rare to find a real exception.