¿Cómo definir un comando que copia otro comando con un nombre diferente?

¿Cómo definir un comando que copia otro comando con un nombre diferente?

Espero crear un comando que automatice este proceso a continuación

\let\oldhat\hat

con algo en este formato:

\let\old(ARGUMENT)\(ARGUMENT)

Lo intenté

\newcommand{\makeold}[1]{
    \expandafter\let\csname old#1\endcsname\csname#1\endcsname}
\makeold{hat} %This should rename \hat to \oldhat

pero esto me da un error de que tengo demasiados \endcsname. ¿Estoy entendiendo mal el propósito de \csname?

Editar: lo había olvidado \leten mi intento.

Respuesta1

Te falta un \lety un extra \expandafter. Esta definición funciona:

\newcommand{\makeold}[1]{%
   \expandafter\let
       \csname old#1\expandafter\endcsname
       \csname#1\endcsname
}

La ejecución de un comando como este es un poco confusa así que déjame describir cómo funciona este comando:

\makeold{hat}se expande a

\expandafter\let\csname oldhat\expandafter\endcsname\csname#1\endcsname

A continuación, el primero \expandaftersalta sobre el \lety expande el \csname. Expandir \csnamerecursivamente expande cualquier macro hasta que llega \endcsnamey forma una macro a partir de los tokens encontrados de esta manera. En particular, expande el segundo \expandafterque salta sobre \endcsnamepara expandir el segundo \csname, que se convierte \csname hat\endcsnameen \hat. Lo que sobra son las fichas, \let\oldhat\hatque es lo que querías hacer.

Respuesta2

Es más sencillo con etoolbox:

\usepackage{etoolbox}

\newcommand{\makeold}[1]{\csletcs{old#1}{#1}}

información relacionada