# Is there another way to avoid name clash in nested multido?

## Constraints

• I want to use the same name for inner and outer loop.
• I am reluctant to append @ and make use of \makeatletter...\makeatother.

Is there any name-spacing construct to use?

## MWE

The following code will not produce the correct result as the two \i clash.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}
\SpecialCoor
\def\Triangle(#1)#2{{\rput(#1){\multido{\i=0+1}{#2}{\multips(\i,0)(!.5 3 sqrt 2 div){\numexpr#2-\i\relax}{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}

\usepackage[nomessages]{fp}
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
\multido{\i=1+1}{\N}{\Triangle(!\i\space 1 sub \i\space 2 add mul 2 div 0){\i}}
\end{pspicture}
\end{document}


The correct output is as follows.

• You know you can use \iA and \iB... – Werner Nov 20 '13 at 0:29
• @Werner: \A!=\iB that disobeys the given constraint. I know this. – kiss my armpit Nov 20 '13 at 0:31
• Strange request though, since using two different counters (\iA and \iB, say) is far easier than completely redefining the inner-workings of \multido to keep track of the nesting, don't you think? – Werner Nov 20 '13 at 0:34
• @Werner: This question concentrates more on the theoretical aspect than the current practical use. I want to avoid remembering the already used variables when using nested multido. I also don't want to clutter the code with @ that consumes more keystrokes. :-) – kiss my armpit Nov 20 '13 at 0:39
• Would you use the same index for a summation inside a summation? I bet not. Different variables should have different symbols. – egreg Nov 20 '13 at 7:59

## 2 Answers

Avoiding name clashes is achieved by using unique names for each identifier in the loop. However, in this case, passing arguments directly on to the inner \multido means they're not expanded until used, at which time they also need to be set. "Pre-expansion" (declaring macros that contain an expanded version of the arguments) helps avoid this:

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{multido}% http://ctan.org/pkg/multido
\SpecialCoor
\def\Triangle(#1)#2{%
\edef\firstarg{#1}\edef\secondarg{#2}% pre-expand #1 and #2
\rput(\firstarg){\multido{\i=0+1}{\secondarg}{\multips(\i,0)(!.5 3 sqrt 2 div){\numexpr\secondarg-\i\relax}{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}

\usepackage[nomessages]{fp}% http://ctan.org/pkg/fp
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
\multido{\i=1+1}{\N}{\Triangle(!\i\space 1 sub \i\space 2 add mul 2 div 0){\i}}
\end{pspicture}
\end{document}


You can use the \xintFor loop from package xinttools. One does not have to worry then about the name used for the iterated variable.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{xinttools}
\SpecialCoor

% inside a macro, the # for an \xintFor must be doubled
%
\def\Triangle(#1)#2{{\rput(#1)%
{\xintFor* ##1 in {\xintSeq {0}{#2-1}}\do
{\multips(##1,0)(!.5 3 sqrt 2 div)%
{\numexpr#2-##1\relax}%
{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}

\usepackage[nomessages]{fp}
\FPset\N{4}
\FPeval\Width{(N-1)*(N+2)/2+N}
\FPeval\Height{round(root(2,3)*N/2:6)}

\begin{document}
\begin{pspicture}(\Width,\Height)
\xintFor* #1 in {\xintSeq{1}{\N}} \do
{\Triangle(!#1 1 sub #1 2 add mul 2 div 0){#1}}
\end{pspicture}
\end{document}


One can furthermore compute in real time \Width and \Height with xintexpr.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{xintexpr}% loads xinttools automatically
\SpecialCoor

% inside a macro, the # for an \xintFor must be doubled
%
\def\Triangle(#1)#2{{\rput(#1)%
{\xintFor* ##1 in {\xintSeq {0}{#2-1}}\do
{\multips(##1,0)(!.5 3 sqrt 2 div)%
{\numexpr#2-##1\relax}%
{\pspolygon(1,0)(!.5 3 sqrt 2 div)}}}}}

\providecommand\firstofone [1]{#1}

\begin{document}
\def\N {4}
%
% we use \xintthenumexpr for the width as it guarantees
% integer format on output
%
% we use \firstofone to hide parentheses and other things from pspicture
%
\begin{pspicture}(\firstofone{\xintthenumexpr (\N-1)*(\N+2)/2+\N\relax},%
\firstofone{\xinttheexpr round(sqrt(3)*\N/2,6)\relax})
\xintFor* #1 in {\xintSeq{1}{\N}} \do
{\Triangle(!#1 1 sub #1 2 add mul 2 div 0){#1}}
\end{pspicture}
\end{document}


A \firstofone trick had to be used to hide the parentheses. For some reason, putting the whole xintexpr-essions inside braces does not work with pspicture. Braces inside \xintexpr .. \relax have special meaning, one could do \xintthenumexpr{\xinttheexpr..\relax}\relax for the width for example but this is admittedly complicated.