# How does expansion matter?

\newcount\@repeat%
\def\repeat#1#2{%
\@repeat#1\relax%
\ifnum#1>\z@\relax%
\repeat{\@repeat}{#2}#2%
\fi}%
\repeat{2}{1}\\%
\repeat{11}{f}\\%
\repeat{\repeat{2}{1}}{f}% this does not work


The macro \repeat#1#2 repeats the argument #2 a total of #1 times. I expect the last two lines produce the same thing, but the last line is wrong.

Why can't the last line produces the letter f 11 times? Does expandability matter? I don't quite understand it.

How I should edit the code so that they produce the same thing?

-
What should the desired output of the last line look like? I can't discern your intent. For example, this: \repeat{2}{\repeat{5}{f}} does work, producing 10 f characters. –  Steven B. Segletes Apr 15 at 18:37
@StevenB.Segletes: the last line should give eleven letters. –  HYC Apr 15 at 18:50
So that is a "one" digit, and not a lower-case "ell"? –  Steven B. Segletes Apr 15 at 18:51
No letter 'ell'. Repeating digit one twice gives eleven. –  HYC Apr 15 at 18:55
Please always post complete code. Is this intended to be plain tex? latex? –  David Carlisle Apr 15 at 19:58

You get

! Missing = inserted for \ifnum.


because \repeat has

 \ifnum#1>\z@


so #1 has to expand to a number, but it is \repeat{2}{1} which includes many non expandable constructs such as \@repeat, \relax and \advance.

Also although unrelated to the error in this fragment, it is a very bad idea to redefine \repeat as it is part of the basic \loop construct used throughout LaTeX and plain TeX.

This version just uses expansion:

\documentclass{article}

\begin{document}

\makeatletter

\def\xrepeat#1#2{%
\ifnum#1>\z@
\xrepeat{\numexpr#1-1\relax}{#2}#2%
\fi}%
\xrepeat{2}{1}\\%
\xrepeat{11}{f}\\%
\xrepeat{\xrepeat{2}{1}}{f}% this does not work

\end{document}


-
I thought \repeat{2}{1} also expands to the number 11. Now it seems it doesn't. Why? What does it actually expand to? –  HYC Apr 16 at 5:22
@HYC In your original \repeat{2}{1} expands to \@repeat2\relax\ifnum.... where \@repeat is a non expandable reference to a count register. \@repeat2 makes a non-expandable assignment of that register to 2, but assignments always happen after expansion. –  David Carlisle Apr 16 at 9:23

David has already explained why the nested \repeat command can't work and also why it's a bad idea to use the name \repeat.

Here's a different definition, based on expl3: I'd say it's way easier, judge for yourself.

\documentclass{article}
\usepackage{expl3}

\ExplSyntaxOn
\cs_set_eq:NN \xrepeat \prg_replicate:nn
\ExplSyntaxOff

\begin{document}

\xrepeat{2}{1}\\
\xrepeat{11}{f}\\
\xrepeat{\xrepeat{2}{1}}{f}

\end{document}


## Explanation

The expl3 package suite already provides the function you want to define and it's called \prg_replicate:nn. So we just make an alias for it. C'est tout.

-