Case sensitivity
FAQ: Is Common Lisp really case-sensitive?

The common misconception is that Common Lisp is case insensitive. This is not true - symbols in Common Lisp are case sensitive.

By default, the Common Lisp reader is case-converting: all unescaped characters in a symbol name get upper-cased. This gives the practical effect of making it seem as though symbol case doesn't matter. This is desirable behavior for interfacing with other case-insensitive languages (such as Fortran), but a pain to interface with case-sensitive ones (such as C).

Luckily the behavior of the reader can be customized via readtable-case.

The one that might seem to be most useful for having case-sensitive symbols at first glance is :preserve, however remember that all code read in with the default setting (:upcase) is in upper-case, as are all the standard Common Lisp symbols (this is defined by the standard), so this means you will need to spell out all CL and external symbols IN ALL UPPERCASE. To make this less annoying, the :invert readtable-case is the most practical: all-lowercase symbol names become uppercase, all-uppercase become lowercase, and mixed-case stays mixed-case (the important part for case sensitivity). The Lisp printer outputs symbol names correctly this way by default. The only problem now becomes inconsistent spelling of a symbol in all lowercase or all uppercase in old code that expects case conversion. But otherwise you can get case sensitivity for your software by setting readtable-case to :invert today.

A convenient library for managing readtable-case and reader macros in your projects is named-readtables.


FAQ: What is the pipe-symbol syntax for symbols, eg. |FooBar123|? What does it have to do with case sensitivity?

In Common Lisp, symbol names can be arbitrary strings - including spaces, control characters, etc. To be able to read and print symbols with unusual names, the vertial bar (||) escape syntax is provided. The characters in a symbol specified with the vertical bar are read as-is and are never case converted. So |Foo " Bar| is read in as a symbol with the name "Foo \" Bar"

While this can be used to get the effect of case-sensitive symbols regardless of what readtable-case is set to, it is obviously more cumbersome.

Section 2.3.4 of the Hyperspec has more examples of the vertical bar syntax.