# Swap many pair of command names in a row

I've learnt from this post how to swap two commands using the let primitive:

\let\temp\first
\let\first\second
\let\second\temp
\let\temp\undefined

Now, in order not to flood my preamble with this pattern, and to ease maintenance of my document, I wish to loop over this to perform all my swaps at once, with something like:

\foreach \lhs/\rhs in {%
phi/varphi,%    easier to..
sim/thicksim,%  .. tweak and maintain ..
% ...           .. with a long list of swaps
} {%
% .. what to input here?
% \expandafter\let\csname\lhs\endcsname\csname\rhs\endcsname
% does not work, because \let seems confined inside the loop scope
}

How do I perform all my swaps in a row like this?
Why is there not an \xlet like there is a \xdef?

This works by parsing a comma separated list of \first/\second macros using listofitems. For the particular example, \swap{\phi/\varphi,\alpha/\beta}, this puts \phi into \swaplist[1,1] (after expanding twice the latter macro), \varphi into \swaplist[1,2], \alpha into \swaplist[2,1] and \beta into \swaplist[2,2].

Now all that is required is a loop through the first index (performed with \foreachitem) to do what the OP showed at the top...a series of \global\lets. The particulars are a game of expansion, so that the \swaplist macros are twice expanded at the time of the \let.

\documentclass{article}
\usepackage{listofitems}
\def\swapA{\let\temp}
\newcommand\swap[1]{%
\setsepchar[-]{,-/}%
\foreachitem\x\in\swaplist{%
\expandafter\expandafter\expandafter\swapA\swaplist[\xcnt,1]%
\edef\swapB{\noexpand\global\noexpand\let\swaplist[\xcnt,1]}%
\expandafter\expandafter\expandafter\swapB\swaplist[\xcnt,2]%
\edef\swapC{\noexpand\global\noexpand\let\swaplist[\xcnt,2]}%
\expandafter\swapC\temp%
}%
}
\begin{document}
\swap{\phi/\varphi,\alpha/\beta}
\noindent phi: $\phi$\\
varphi: $\varphi$\\
alpha: $\alpha$\\
beta: $\beta$
\end{document}

If the alternate syntax is desired, that omits the backslashes, \swap{phi/varphi,alpha/beta}, then this would suffice, to accomplish the same task. Double expansion is no longer needed, since \csname will fully expand its \swaplist argument.

\documentclass{article}
\usepackage{listofitems}
\def\swapA{\let\temp}
\newcommand\swap[1]{%
\setsepchar[-]{,-/}%
\foreachitem\x\in\swaplist{%
\expandafter\swapA\csname\swaplist[\xcnt,1]\endcsname%
\edef\swapB{\noexpand\global\noexpand\let\csname\swaplist[\xcnt,1]\endcsname}%
\expandafter\swapB\csname\swaplist[\xcnt,2]\endcsname%
\edef\swapC{\noexpand\global\noexpand\let\csname\swaplist[\xcnt,2]\endcsname}%
\expandafter\swapC\temp%
}%
}
\begin{document}
\swap{phi/varphi,alpha/beta}
\noindent phi: $\phi$\\
varphi: $\varphi$\\
alpha: $\alpha$\\
beta: $\beta$
\end{document}
• Wow. This seems to work indeed Ô.Ô What's the idea? Is the \foreach option a dead-end, and why? – iago-lito 'considering leaving Apr 16 '18 at 12:01
• @iago-lito I added some commentary. – Steven B. Segletes Apr 16 '18 at 12:06
• Well, cheers :) I'll have a look into this listofitems package, which seems quite powerful. Anyway, it looks like LaTeX remains quite hard to read and write for humans, right? XD – iago-lito 'considering leaving Apr 16 '18 at 12:09
• @iago-lito I have added an alternate version, if you prefer the syntax without backslashes, \swap{phi/varphi,alpha/beta} – Steven B. Segletes Apr 16 '18 at 12:12
• @iago-lito The listofitems package is extremely powerful and handy for dissecting complex lists. Documentation here: ctan.org/pkg/listofitems, and also search for listofitems on this tex.stackexchange website for ways it can be used. – Steven B. Segletes Apr 16 '18 at 12:16