Defining characters as macros

Both Plain TeX and LaTeX define a character as a macro: the character expands to a "non-breakable space". Since Knuth wrote the first such macro ever, no-one expects anything other than that will do such a thing; the slightly surprising thing is how difficult it is to get such things right for oneself.

A character's category code (catcode) must be set to "active" before you can define a meaning of the character as a command. There is no reason in principle that one shouldn't set any character 'active', and apply a definition to it as a macro. The problem is that by so doing, you preclude the character's use for other purposes, and there are few characters "free" to be subverted in this way.

Some packages facilitate such definitions - for example, the shortvrb package in its \MakeShortVerb command. The doc package, which processes .dtx files uses shortvrb to define textbar...textbar as a shorthand for \verbtextbar...textbar. But textbar is also used in the preambles of tabular environments, so that tables in .dtx files can only have vertical line separation between columns by employing special measures of some sort - a typical example of the sort of problem that unconstrained use of active characters can produce.

To define the character z as a command, one would therefore say something like:

  \catcode`\z=\active
  \def z{Yawn, I'm tired}%
and each subsequent z in the text would become a yawn. This would be an astoundingly bad idea, for any but the most specialised document. (Note that, in \def z, z is no longer a letter; the space is therefore not necessary - \defz would do; we choose to retain the space, for what little clarity we can manage.)

However, the definition of the command persists even if the character's catcode reverts to its original value; the definition becomes accessible again if the character once again becomes active. This fact is the basis of most "safe" uses of character definitions.

To define a character as a command "safely" (i.e., storing it for later use), we need to isolate the definition in a group. The simple way of doing this is:

{%
  \catcode`\z=\active
  \gdef z{Yawn, I'm tired}%
}%
Use of \gdef (global definition) ensures that the definition persists after the group is closed, even though the catcode reverts.

The alternative ("tricksy") way of creating such an isolated definition depends on the curious properties of \lowercase, which changes characters without altering their catcodes. Since there is always one active character ( ), we can fool \lowercase into patching up a definition without ever explicitly changing a catcode:

\begingroup
  \lccode`\~=`\z
  \lowercase{\endgroup
    \def~{Yawn, I'm tired}%
  }%

The two definitions have the same overall effect (the character is defined as a command, but the character does not remain active), except that the first defines a \global command.