# Why do paramaters of \renewcommand need to double up the # within a \foreach

## Introduction:

When you use \renewcommand within another macro or environment, one needs to double up the ## to access the parameters of the inner macro. This serves as a way to distinguish the inner macros ##1 with the outer macros #1 (even if the outer macro does not have any parameters, it provides for error checking). For example:

\newcommand*{\OuterCommand}{%
\renewcommand*{\SomeCommand}[1]{\color{red}##1}%
....
}%


The references below provide more details on this.

## Issue:

It appears that the same doubling up of the # is needed within a \foreach loop as illustrated in the MWE below.

This took me quite some time to figure this out as the error message that the MWE below gives is:

Illegal parameter number in definition of \pgffor@body

This was within a very deeply nesting of \foreach loops, so I was sure the problem was that I was nesting the \foreach too deeply. Surprisingly, if you skip past the error, the output is still correct, so this made it even harder to locate the problem.

## Questions:

• Since the \foreach does not have parameters like #1 (as \newcommand does), why is it necessary to double up the # within a definition within a \foreach?
• How is that the output is still correct, if you simply ignore the error and hit return to continue processing?

## Code:

\documentclass{article}
\usepackage{xcolor}
\usepackage{pgffor}

\newcommand*{\MyList}{A,B,C}%
\newcommand{\SomeCommand}[1]{#1}%

\begin{document}
\foreach \x in \MyList {%
\renewcommand*{\SomeCommand}[1]{\color{red}#1}%  Using ## here eliminates the error.
\par\SomeCommand{\x}%
}%
\end{document}

-
Actually you don't need to use ##1 "to access the parameters of the inner macro" it is simply that you need to use ## to enter #. –  David Carlisle Sep 15 '12 at 8:35
@DavidCarlisle: Interesting way to look at it. Never thought if # as escaping the #. But, then how do you explain that you need 4 for the next level? :-) –  Peter Grill Sep 15 '12 at 9:20
I'll add some notes to the answer, code formatting in comments is rubbish –  David Carlisle Sep 15 '12 at 9:38
Related Question: How to insert a # via \immediate\write18 within a macro. –  Peter Grill May 18 at 22:50

Internally the definition of foreach will be saving the body of the loop in a macro so it is like (if looping over a,b,... )

\def\body{%
\renewcommand*{\SomeCommand}[1]{\color{red}#1}%  Using ## here eliminates the error.
\par\SomeCommand{\x}%
}%
}
\def\x{a}\body
\def\x{b}\body
...


That initial \def (or \newcommand if you prefer) will require a # in the body to be entered as ##. As shown above you would get an error on #1 as \body doesn't take parameters it would have to be entered, as you found, as ##1.

It is possible to define loops in such a way not to require this (for example it could use a token register rather than a macro for saving the body) but that is apparently not the case here.

Note that the need to double # is unrelated to the fact that there is an inner macro definition. It is not that inner macros require ##1 to refer to the first parameter, it is simply that the inner macro definition requires the two tokens # and 1 to refer to the first parameter and to get a # into a macro body you need ##. To see this consider a definition that doesn't have ##1.

You can go

\let\hash=#


and \hash will be let to # but you can not define a macro as

\def\definehash{\let\hash=#}


as that generates

! Illegal parameter number in definition of \definehash.


You need ## to refer to a literal # in a macro definition. So it needs to be

\def\definehash{\let\hash=##}


You ask in comments why it needs four # for a double nested definition. Again it is nothing special about the inner definitions, they never "see" ##1 by the time they are evaluated they just see a single #. If you tried to define

\def\ddefinehash{\def\definehash{\let\hash=##}}


The definition would proceed without error but then if you try to execute \ddefinehash you find that it just has a single # in its definition and so you get the error as before:

! Illegal parameter number in definition of \definehash.
}
l.12 \ddefinehash


So you need to get two # into the definition of \definehash and each of those has to be entered as ## so you end up with

\def\ddefinehash{\def\definehash{\let\hash=####}}


Putting it all together:

{
\let\hash=#
}

{
\def\definehash{\let\hash=##}
}

{
\def\ddefinehash{\def\definehash{\let\hash=####}}
\ddefinehash
\definehash

\show\ddefinehash
\show\definehash
\show\hash
}

\bye


> \ddefinehash=macro:
->\def \definehash {\let \hash =####}.
l.15 \show\ddefinehash

?
> \definehash=macro:
->\let \hash =##.
l.16 \show\definehash

?
> \hash=macro parameter character #.
l.17 \show\hash

?
)
No pages of output.

-