3

I use the same preamble in several projects. The set of already-defined commands is different between the environments. In one project, \eps is already defined, whereas in another it is not. I wish to define \eps as \varepsilon.

The Latex2e unofficial reference manual says:

If you try to define a command and the name has already been used then you get something like <error>. If you try to redefine a command and the name has not yet been used then you get something like <different error>.

Therefore, neither can be used in my situation. I can get around the issue like this:

\ifdefined\eps
    \renewcommand{\eps}{\varepsilon}
\else
    \newcommand{\eps}{\varepsilon}
\fi

but this is quite clunky. I don't understand why \renewcommand should complain if the command does not already exist. Either way, we are supplying our desired definition of the command.

2
  • 2
    To avoid checks on pre-definition, you could use \def\eps{\varepsilon}. This will work whether \eps is predefined or not. Oct 12 '20 at 2:55
  • 1
    You may use \providecommand as explained here. If cmd is not defined, providecommand defines it.
    – FHZ
    Oct 12 '20 at 3:22
13

"Why" questions are hard to answer. In this case the answer is "Because Leslie Lamport chose this definition in the early 1980s".

However if \renewcommand acted as you suggest then it would be equivalent to \newcommand with no check on the command being defined at all. This would negate much of the reason for having \newcommand which is to protect the user from accidentally redefining latex internals and breaking the system.

As Steven comments under your question, the behaviour would then be like the TeX primitive \def which always defines (or redefines) the supplied command. Even now you often see users using \def in latex documents and overwriting internal commands.

The idea is that you use \newcommand and get warned if something is about to go wrong, and then only if you know that it is Ok to do so, use \renewcommand for redefinitions.

You could define your command more simply as

  \def\zzcommand#1{\let#1\undefined\newcommand#1}

which undefines the command first so that \newcommand always succeeds, but then try

\zzcommand\box{\fbox{X}}

for example.

6

If in one of the environments \eps has already been defined to give one of the forms of epsilon, you just do

\providecommand{\eps}{\varepsilon}
\renewcommand{\epsilon}{\varepsilon}

and usage of \eps will produce \varepsilon in both environments.

If \eps is defined to do something else, then you're doomed.


Why does \renewcommand balk if fed with an undefined command? Because \renewcommand should be used with care and knowing what one is doing.

2
  • "If \eps is defined to do something else, then you're doomed." – why? Won't this code just redefine it as \varepsilon? Oct 12 '20 at 22:28
  • @PaŭloEbermann Yes, but the people using it with another meaning would be appalled.
    – egreg
    Oct 12 '20 at 22:38
2

This is a simple example from Leo Liu's answer here.

\providecommand only redefines the command \foo if this command is not previously defined.

If \newcommand defines \foo, then \providecommand will be silented.

With \providecommand, there will always exist a \foo to become meh through \renewcommand.

I'm not sure if this is the most elegant answer, but it is very simple and clear.

\documentclass{article}
% (un)comment to change \providecommand behavior
\newcommand{\foo}{foo}
% if {\foo} not defined, then {\foo} is ``bla''
\providecommand{\foo}{bla}
% {\foo} will always become ``meh''
\renewcommand{\foo}{meh}
\begin{document}
{\foo}
\end{document}
3
  • Unless I misunderstand, \providecommand is not equivalent to the \if statement in my question. If \eps is already defined, I want to change it, not use the current definition.
    – japreiss
    Oct 12 '20 at 4:10
  • 1
    Oh nevermind, I get it now. The combination of the empty \providecommand followed by the \renewcommand is the suggested idiom, correct?
    – japreiss
    Oct 12 '20 at 4:12
  • @japreiss, that's correctly. Indeed, i almost gave you this exactly wrong answer by forgetting the renewcommand line. This syntax keeps your commands at the LaTeX level, without digging further into the TeX level.
    – FHZ
    Oct 12 '20 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.