Important update
The LaTeX kernel from the 2020-10-01 release has \NewCommandCopy that does the same job of \LetLtxMacro and better. It also provides \ShowCommand to obtain the internal definition also of robust commands. So the code below should now be
\NewCommandCopy{\oldemph}{\emph}
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}
The analysis below about the problems with \let is still valid.
Original answer
While something such as
\let\oldemph\emph
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}
seems to work, it really doesn't, because \emph is defined with \DeclareRobustCommand. Where doesn't it work? suppose you write that code and then use \emph in a caption:
\caption{This is \emph{emphasized}}
what is written in the .aux file is
\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces This is \textbf {\emph {emphasized}}}}{1}}
This is because the original expansion of \emph is
\protect\emph§
(where with § I'm denoting a space in the name). So the \emph{emphasized} in the caption gets expanded successively into
\textbf{\oldemph{emphasized}}
\protect\textbf§{\protect\emph§{emphasized}}
\textbf§{\emph§{emphasized}
and written as
\textbf {\emph {emphasized}}
(because TeX adds a space after a command name when writing). In this case, when reading the file for building the List of Figures or Tables, TeX will find
\textbf{\textbf{\oldemph{emphasized}}}
which is innocuous. But it's not very difficult to imagine situations where this can lead to infinite loops.
The package letltxmacro prevents this problem:
\usepackage{letltxmacro}
\LetLtxMacro{\oldemph}{\emph}
\renewcommand{\emph}[1]{\textbf{\oldemph{#1}}}
would be a safer way to proceed.
Never use \let on commands defined with \DeclareRobustCommand or commands defined with \newcommand and having an optional argument.
The former can be recognized by the fact that \show\command returns
> \command=macro:
->\protect \command .
The latter are distinguished by the fact that \show\command returns
> \command=macro:
->\@protected@testopt \command \\command {...}.
(where ... is actually the default for the optional argument).
\let\oribfseries\bfseries\DeclareRobustCommand\bfseries{\oribfseries\itshape}– egreg Nov 24 '23 at 09:01NewCommandCopyto a new command. Imagine I would like to redefine a couple of commands and not just one (e.g., to add a new textcolor to them or make them italic). Could we make a macro\colorize{\llbracket}{blue}that redefines\llbracketto be wrapped in\textcolorbut so we do not have to spell out the two lines again and again? I tried something like\expandafter\NewCommandCopy\csname old#1\endcsname{\csname #1\endcsname}to generate the name for the old macro but it didn't work. – PaulProgrammerNoob Mar 20 '24 at 20:39\NewCommandCopyand similar commands is clumsy. You can make a new question. Leave a comment here when you do it. – egreg Mar 20 '24 at 21:21