Using \let with \csname inside a macro

The problem with the OP's syntax is that the first \csname of the \let was expanded into a token, but not the 2nd. One nice trick (learned from David C) is that you can insert \expandafter inside a \csname, just before the \endcsname, to expand the next thing that follows, before closing out the first \csname expansion! That is what I do here, so that both \csnames are expanded into cs-tokens, before the \let is evaluated.

\documentclass{article}

\newcommand*\letprefix[2]{%
  \expandafter\let\csname#1\expandafter\endcsname\csname#1#2\endcsname}

\newcommand*\mycommandversion{I want to use this as ``\textbackslash
  mycommand''}
\letprefix{mycommand}{version}

\begin{document}
Hello!
\mycommand
\end{document}

enter image description here


With etoolbox you already have a handy tool:

\documentclass{article}
\usepackage{etoolbox}

\newcommand*\letprefix[2]{%
  \csletcs{#1}{#1#2}%
}

\newcommand*\mycommandversion{I want to use this as ``\textbackslash mycommand''}
\letprefix{mycommand}{version}

\begin{document}
Hello!
\mycommand
\end{document}

No need to remember complex sequences of \expandafter.


The answer of Steven B. Segletes says it all.

An alternative less efficient approach is exchanging tokens after applying \csname..\endcsname:

\documentclass{article}

\newcommand\exchange[2]{#2#1}%
\newcommand*\letprefix[2]{%
  \expandafter\exchange\expandafter{\csname#1#2\endcsname}{%
    \expandafter\let\csname#1\endcsname= %
  }%
}%

\newcommand*\mycommandversion{%
  I want to use this as ``\textbackslash mycommand''%
}%

\letprefix{mycommand}{version}

\begin{document}
Hello!
\mycommand
\end{document}

This is a link to the .jpg-file of Steven B. Segletes' answer.
(The image comes from a link to the .jpg-file of Steven B. Segletes' answer.)


A more "generic" approach to the matter could be a macro \NameToCs:

The TeXbook explains a nice feature when it comes to defining macros: In the ⟨parameter text⟩ of a macro-definition you can use #{-notation for a macro whose last argument will be delimited by a left curly brace { which—unlike other argument-delimiters—will be re-inserted as if it had been left in place.

Thus I sometimes use a macro-mechanism \NameToCs which processes an argument which is delimited by a left curly brace ({) and another argument which is nested in curly braces.

The argument nested in curly braces is taken for the name of a ⟨control sequence token⟩ which is to be constructed via \csname..\endcsname.

\NameToCs works as follows:

\NameToCs⟨stuff not in curly braces⟩{NameOfCs}
→
⟨stuff not in curly braces⟩\NameOfCs

(If you wish to obtain only the control-sequence-token \NameOfCs, then you can leave ⟨stuff not in curly braces⟩ empty: \NameToCs{NameOfCs} → \NameOfCs)

\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\makeatother

There are various uses for such a macro:

  1. \NameToCs{foo}\foo
  2. \NameToCs\string{foo}\string\foo
  3. \NameToCs\meaning{foo}\meaning\foo
  4. \NameToCs\global\long\def{foo}...\global\long\def\foo...
  5. \NameToCs\newcommand*{foo}...\newcommand*\foo...
  6. \NameToCs\NameToCs\global\let{foo}={bar}\NameToCs\global\let\foo={bar}\global\let\foo=\bar

Usage-example 6 can be applied in your scenario:

\documentclass{article}

\makeatletter
\newcommand\exchange[2]{#2#1}%
\@ifdefinable\NameToCs{\long\def\NameToCs#1#{\romannumeral0\innerNameToCs{#1}}}%
\newcommand\innerNameToCs[2]{\expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}}%
\makeatother

\newcommand*\mycommandversion{%
  I want to use this as ``\textbackslash mycommand''%
}%

\newcommand*\letprefix[2]{%
  \NameToCs\NameToCs\let{#1}= {#1#2}%
}%

\letprefix{mycommand}{version}

\begin{document}
Hello!
\mycommand
\end{document}

This is a link to the .jpg-file of Steven B. Segletes' answer.
(The image comes from a link to the .jpg-file of Steven B. Segletes' answer.)


Be aware that a simple \let-assignment does not always work out for control-sequences which initiate the carrying-out of a "macro-based mechanism" that internally consists of several macros.

  • This is the case, e.g., with LaTeX commands that process optional arguments defined in terms of \newcommand or with LaTeX commands that are defined as robust macros by \DeclareRobustCommand.
    With such commands the command \LetLtxMacro of the package letltxmacro takes care of the internal macros also.
  • This is also the case with commands defined in terms of xparse's \NewDocumentCommand.