21

Does there exists a version of \newcommand, something like \extranewcommand{\foo}{bar} which does defines \foo to stand for bar regardless of whether \foo has been previously defined? Of course, if \foo is undefined, one can use \newcommand{\foo}{bar}, and if it is defined, one can use \renewcommand{\foo}{bar}. However, in either case, one has to know which version to use: if one chooses wrong, the document won't compile. What I am interested in is if there exists a similar command (or perhaps a combination of commands, etc.) which will work in either situation.

As a rationalisation for the question, below are two situations in which I would find this command useful. Of course, the change is very minor, but it adds up over time, I think.

  1. One doesn't always know what commands are already defined. Sometimes, it happens that a newly defined command happens to also be something defined in some standard package. For instance, one wants to use \operatorname{Im} for the image of a linear operator, so it is convenient to declare \newcommand{\Im}{\operatorname{Im}}. However, \Im is already a fancy symbol for the imaginary part, so a renewcommand is needed instead. I never use the mentioned imaginary part symbol, so it would be nice if I could just forget that it exists (but I can't). (Of course, this issue can be solved by compiling, noticing the error and adding "re" in front of "newcommand"; but, there are a lot of other such clashes that happen.)
  2. I use a lot of commands used only "locally" (I'm not sure if it's a good coding practice, but I find it useful). For example, if I have a set S which occurs in many places in the text, I would often declare \newcommand{\Set}{S} or even \newcommand{\S}{S}, so that I can easily change the symbol S to another one if I feel like it. This potentially leads to renewing commands quite frequently, which is not that much of a problem. However, if a block of text with a \newcommand moves, then also a prefix re has to move. (Again, it is not much of a problem, but I find it a nuisance).
  • 7
    please be very careful! an author redefined \i to be a math function, failing to notice that one of the items in the bibliography was by a russian author whose transliterated name required \i (for use with a breve). it took a ridiculously long time for the production team to figure out (1) why there was a message that math mode was required, and (2) change all the other instances of \i to something else (and hoping that no mistakes were made in the process). – barbara beeton Aug 18 '13 at 14:08
  • One way to mitigate the risk that @barbarabeeton mentioned is to localize your defined commands by using brackets. For example {\renewcommand\sum{s_{um}} $\sum$} $\sum$ would have the same result as typing $s_{um}$ $\sum$ because the renewed command only remains defined within the brackets. – Jasha Jun 2 '18 at 8:21
28

There is \providecommand that defines a macro if it is not yet defined. Together with \renewcommand you have your "\extranewcommand":

\providecommand{\foo}{}
\renewcommand{\foo}[1]{bar: #1}

Or you can switch to the plain TeX primitives (other syntax!), e.g.:

\long\def\foo#1{bar: #1}

(\renewcommand and friends without star use \long\def and if the star form is given, \def without \long is used. Also the parameters are specified differently.)

\declarecommand

A definition of the "requested" \declarecommand that calls \providecommand and \renewcommand together:

\documentclass{article}

\makeatletter
\newcommand*{\declarecommand}{%
  \@star@or@long\declare@command
}
\newcommand*{\declare@command}[1]{%
  \provide@command{#1}{}%
  % \let#1\@empty % would be more efficient, but without error checking
  \renew@command{#1}%
}
\makeatother

\begin{document}

\declarecommand*{\foo}{\typeout{foo 1: \meaning\foo}}
\foo
\declarecommand{\foo}{\typeout{foo 2: \meaning\foo}}
\foo
\declarecommand*{\foo}[1]{\typeout{foo #1: \meaning\foo}}
\foo{3}

\end{document}

Result:

foo 1: macro:->\typeout {foo 1: \meaning \foo }
foo 2: \long macro:->\typeout {foo 2: \meaning \foo }
foo 3: macro:#1->\typeout {foo #1: \meaning \foo }
  • To be equal to renewcommand & friends, it should be \long\def\foo#1 – Marco Daniel Aug 18 '13 at 13:07
  • 2
    And one could define \newcommand\declarecommand[1]{\providecommand{#1}{}\renewcommand{#1}} – egreg Aug 18 '13 at 13:21
  • @MarcoDaniel: The star forms of \renewcommand and friends use \def without \long. – Heiko Oberdiek Aug 18 '13 at 13:28
  • @egreg: Done, a bit more elaborate because of the star forms. – Heiko Oberdiek Aug 18 '13 at 13:44
  • @HeikoOberdiek I had already upvoted your answer. ;-) – egreg Aug 18 '13 at 13:45
2

It's not as crafty as Heiko's answer but another option would be

\ifdefined\foo
\renewcommand{\foo}[1]{bar: #1}
\else
\newcommand{\foo}[1]{bar: #1}
\fi

Note that \ifdefined is part of the e-TeX extension and as such part of any modern LaTeX compiler. No packages required.

1

You can put

\newcommand{\foo}[1]{to be renewed}

in your preamble and then

\renewcommmand{\foo}[1]{whatever #1}

wherever you like.

If \foo happens to be defined when you start out, you'll find that out and can choose another name, or renew in your preamble.

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.