Define a macro in terms of other macro names

With your present code

\def\expandafter\csname\a\b\endcsname{\c}

you are overwriting the TeX primitive \expandafter such that it must be followed by \csname\a\b\endcsname. Then the construct

\expandafter\csname\a\b\endcsname

will expand to \c. With an empty document nothing happens, but try to type something and you'll get a puzzling

! Use of \expandafter doesn't match its definition.

What you do want is to hold \def for a while, so you must put the \expandafterbefore it. The code

\documentclass{article}

\begin{document}

\def\a{A}
\def\b{B}
\def\c{CC}
\expandafter\def\csname\a\b\endcsname{\c}
\AB
\end{document}

will do what you expect.

My favourite reading about \expandafter: A Tutorial on \expandafter (TUGboat 9)


The control sequences \a, \b and \c are already defined in the LaTeX 2ε-kernel.

\MYa, \MYb and \MYc will be used instead.

For the sake of having fun playing around with (La)TeX's expansion-mechanisms, I offer the following approaches:

With this approach \csname's triggering of expansion until finding a matching\endcsname is used in combination with \expandafter for tricking LaTeX into expanding things behind the \csname..\endcsname-construct as well:

% Use LaTeX for compiling this:

\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}

\expandafter\newcommand\csname\MYa\MYb\expandafter\endcsname\expandafter{\MYc}

\show\AB

\stop

You can also combine \expandafter with \exchange:

% Use LaTeX for compiling this:

\newcommand\exchange[2]{#2#1}

\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}

\expandafter\exchange\expandafter{\expandafter{\MYc}}{\expandafter\newcommand\csname\MYa\MYb\endcsname}%

\show\AB

\stop

In many situations a variant of \exchange is useful which adds curly braces:

% Use LaTeX for compiling this:

\newcommand\PassFirstToSecond[2]{#2{#1}}

\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}

\expandafter\PassFirstToSecond\expandafter{\MYc}{\expandafter\newcommand\csname\MYa\MYb\endcsname}%

\show\AB

\stop

There is also the macro \name which takes everything before the first pair of curly braces for one argument and everything within the first pair of curly braces for another argument and which returns things after having applied \csname..\endcsname to the things within curly braces:

\name\newcommand{macro}...\newcommand\macro...
\name\global\long\def{macro}...\global\long\def\macro...
\name\string{macro}\string\macro
\name{macro}\macro
\name\name\let{macroA}={macroB}\name\let\macroA={macroB}\let\macroA=\macroB

 

% Use LaTeX for compiling this:

\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}

\newcommand\exchange[2]{#2#1}%    
\csname @ifdefinable\endcsname\name{%
  \long\def\name#1#{\romannumeral0\innername{#1}}%
}%
\newcommand\innername[2]{%
  \expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}%
}%

\name\expandafter\newcommand\expandafter{\MYa\MYb}\expandafter{\MYc}%
% ->
% \romannumeral0\innername{\expandafter\newcommand\expandafter}{\MYa\MYb}\expandafter{\MYc}
% ->
% %\romannumeral0-expansion in progress
% \expandafter\exchange\expandafter{\csname\MYa\MYb\endcsname}{ \expandafter\newcommand\expandafter}\expandafter{\MYc}%
% -> ( \expandafter-chain "hits" \csname )
% %\romannumeral0-expansion in progress
% \exchange{\AB}{ \expandafter\newcommand\expandafter}\expandafter{\MYc}%
% ->
% %\romannumeral0-expansion in progress
% <space>\expandafter\newcommand\expandafter\AB\expandafter{\MYc}%
% ->
% %\romannumeral0-expansion terminated:
% \expandafter\newcommand\expandafter\AB\expandafter{\MYc}%
% -> ( \expandafter-chain "hits" \MYc )
% \newcommand\AB{CC}%

\show\AB

\stop

In case \PassFirstToSecond is available:

% Use LaTeX for compiling this:

\newcommand*\MYa{A}
\newcommand*\MYb{B}
\newcommand*\MYc{CC}

\newcommand\PassFirstToSecond[2]{#2{#1}}%    
\newcommand\exchange[2]{#2#1}%    
\csname @ifdefinable\endcsname\name{%
  \long\def\name#1#{\romannumeral0\innername{#1}}%
}%
\newcommand\innername[2]{%
  \expandafter\exchange\expandafter{\csname#2\endcsname}{ #1}%
}%

\expandafter\PassFirstToSecond\expandafter{\MYc}{\name\newcommand*{\MYa\MYb}}%

\show\AB

\stop

My favourite reading about \expandafter (and about how to keep the amount of \expandafter short) is the thread "How can I know the number of expandafters when appending to a csname macro". ;-)

Tags:

Macros