# How to define _or_ redefine a command (mixing \providecommand + \renewcommand)?

In some situations I wish there was a way to define a command \tmp so that

• if \tmp does not exist: Defined \tmp
• if \tmp does exits: Redefine \tmp


In this question I learned about \providecommand, which almost solves my problem: It can be used irrespective of whether \tmp is defined, but it only defines on the first occurrence and does not overwrite. This lead me to the naive attempt:

\newcommand{\overwritecommand}[2]{
\providecommand{#1}{#2}
\renewcommand{#1}{#2}
}


However, this approach is obviously not general enough:

% it works for
\overwritecommand{\tmp}{test}

% but not for commands with arguments like
\overwritecommand{\tmp}[1]{test: #1}
% Error: You can't use macro parameter character #' in horizontal mode.


Is there any other way to achive the define or overwrite behavior?

• Do you mean \def? – jon Feb 18 '15 at 18:13
• @jon: Does \def somehow allow to use optional arguments as well? – bluenote10 Feb 18 '15 at 18:15
• It can be used that way. The package xparse has \DeclareDocumentCommand, which is much easier to use; there's also various \def-related commands in the package etoolbox. – jon Feb 18 '15 at 18:18

Yes, there is a method:



Why does it work? Because TeX uses macro expansion and it's irrelevant what \providecommand defines #1 to be, if #1 wasn't defined, because you redefine it immediately.

Now that you know how to do it, try

\declarecommand{\box}[1]{\fbox{#1}}


and enjoy the wreck!

There is a reason why LaTeX doesn't provide a \declarecommand function: you MUST be aware whether you are redefining an existent command.

If you want to allow the optional *, then

\makeatletter
\newcommand\declarecommand{\@star@or@long\@declarecommand}
\newcommand\@declarecommand[1]{%
\provide@command{#1}{}%
\renew@command{#1}%
}
\makeatother


will do.

• Drat: I was just posting more or less the same thing but was held up thinking about the optional star and whether to handle it! – Joseph Wright Feb 18 '15 at 18:18
• @JosephWright It would be easy to comply with the optional *, but the idea is wrong to begin with! – egreg Feb 18 '15 at 18:19
• Thanks. Took me a moment to see how it works. Nice trick! – bluenote10 Feb 18 '15 at 18:25
• this looks evil. hope i never have to debug a journal submission that uses it. – barbara beeton Feb 18 '15 at 18:28
• @barbarabeeton I hope I made clear why one shouldn't use it. There are several ways to shoot one's own foot, this one is quite funny. – egreg Feb 18 '15 at 19:01


\def\newcommandA#1[#2]{\edef\tmpp{\ifcase#2%
\or1\or12\or123\or1234\or12345\or123456\or1234567\or12345678\or123456789\fi}%
\isnextchar[{\newcommandB#1}{\long\expandafter\def\expandafter#1\tmpp}%
}
\def\newcommandB#1[#2]{%
\def#1{\isnextchar[{\runcommand#1}{\runcommand#1[#2]}}%
\long\expandafter\def\csname\string#1X\expandafter\endcsname\tmpp
}
\long\def\runcommand#1[#2]{\csname\string#1X\endcsname{#2}}


Since the classic examples have already been shown, I'll just add the xparse way, which is quite user-friendly:

\documentclass{article}
\usepackage{xparse}
\DeclareDocumentCommand{\foo}{m}
{Foo: #1}
\begin{document}

\foo{bar}

\DeclareDocumentCommand{\foo}{om}
{\IfNoValueTF{#1}%
{Bar: no optional, just #2}%
{Bar: optional = #1, plus #2}%
}%

\foo{Baz}

\foo[Bar]{Baz}

\end{document}
`