5

We (or at least I) usually think of an active character as just another command whose name just happens to a character rather than a control sequence. So why does \newcommand<active character> not yield an error if the <active character> was already defined?

\documentclass{article}

\begin{document}

\newcommand\newcommand{coffee} % error

\newcommand~{coffee} % no error

~

\end{document}
4
  • 1
    Interestingly, \newcommand\~{coffee} does give the error.
    – Marijn
    Commented Sep 24, 2022 at 12:49
  • @Marijn Not really surprising as \~ is an actual control sequence with an existing definition that is completely different from that of ~ (right, se\~norita)?
    – Gaussler
    Commented Sep 24, 2022 at 12:52
  • Ah yes, you're right - I somehow mistakingly thought that ~ was a shorthand for \~ but that doesn't make sense. By the way I'm a señor :)
    – Marijn
    Commented Sep 24, 2022 at 12:56
  • 1
    @Marijn I guessed as much, but perhaps the señorita I asked was the lovely lady standing right behind you (with a gun to the back of your head). ;-)
    – Gaussler
    Commented Sep 24, 2022 at 12:58

2 Answers 2

6

As with any "why" command about latex the answer is related to the token memory available in 1985 (2.0x) or 1993 (2e)

This century things are different

\documentclass{article}

\begin{document}



\NewDocumentCommand~{coffee} % no error

~

\end{document}

gives

! LaTeX cmd Error: Command '~' already defined.

For immediate help type H <return>.
 ...                                              
                                                  
l.8 
    
? 
1

An answer looking at the source code: First we have the macros \@ifundefined and \@ifdefinable:

ifundefined and ifdefinable documentation

Note that \@ifundefined takes in strings (technically "the name of the control sequence") as the argument, not the control sequence itself.

However \@ifdefinable takes in a control sequence as the input. So if it wants to use \@ifundefined in its implementation, it has to extract the name:

source code of ifdefinable

It's not too hard to see the check only works for control sequences, not active characters.

Side note, assuming nobody wants to use this command when \escapechar is -1 or 32 (space character), it would work correctly.

Side note 2, \@ifundefined, contrary to what its name implies, is supposed to(*) check if the argument's meaning is either undefined or \relax.
Nevertheless, it first uses \ifcsname ... \endcsname to check if it's undefined first, then if it is not, construct the control sequence with the name to check if it's \relax, presumably to save an entry in the hash table when the name is not defined.
(I suspect in pre-ε-TeX days, only the csname-relax check is performed, then after that the ifcsname is added in to save an entry; but to maintain backwards compatibility it still need to check if the meaning is \relax -- although I didn't check this in the old LaTeX source code)

source code of ifundefined

Maybe someone who can find want source code of older LaTeX versions can confirm that these versions use just the csname-\relax check.

(*): Or so I think.

1
  • you can see the date of change and the old definition in the current sources, to allow rollback via latexrelease: % \changes{1.5c}{2018/01/06}{Avoid defining undefined commands to \cs{relax}} Commented Feb 25, 2023 at 14:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .