Skip to content

Instantly share code, notes, and snippets.

@VincentTam
Created August 13, 2025 23:00
Show Gist options
  • Save VincentTam/5b7a52afb4f96f1d5ef0069ffee6b700 to your computer and use it in GitHub Desktop.
Save VincentTam/5b7a52afb4f96f1d5ef0069ffee6b700 to your computer and use it in GitHub Desktop.
LaTeX advanced recursion (use output of an auxiliary function as argument of recursive function)

I was puzzled ats \expandafter, and I started with simple observations. Here're AI-generated explanations.

The command \expandafter is a low-level TeX primitive that controls the order of macro expansion. Its job is to force the expansion of a token that is not immediately next to it.

In the provided code, \expandafter is used to ensure that the recursive call \rrep receives a concrete number as its first argument, rather than an unexpanded macro sequence.

Let's break down the key line from the \rrep macro:

\expandafter\rrep\expandafter{\number\numexpr#1-1\relax}{\rep{#2}}

Normally, TeX expands tokens from left to right. Without \expandafter, TeX would try to execute \rrep and would pass the entire sequence {\number\numexpr#1-1\relax} as the first argument, which is not what we want.

Here's how the \expandafter commands work together:

  1. The first \expandafter is encountered. It skips the next token (\rrep) and looks at the token after that, which is the second \expandafter.
  2. The second \expandafter is now being expanded. It skips the next token ({) and looks at the token after that, which is \number.
  3. The \number\numexpr#1-1\relax sequence is then expanded. For example, if #1 is 4, this sequence is calculated and expands to the literal number 3.
  4. After these forced expansions, the token stream effectively becomes \rrep{3}{\rep{#2}}. The \rrep macro is now called with a simple number (3) as its first argument, which allows the \ifnum conditional check to work correctly on the next recursive step.

In short, \expandafter is essential here to perform the subtraction (\numexpr#1-1) and convert the result to a number (\number) before the recursive call to \rrep is made. This prevents an infinite loop and allows the counter to correctly decrement and eventually reach the base case (#1 <= 0).

I only know some basic resursion. Thinking that typst will replace LaTeX, I don't think I'll spend more time on this and the Expl3 syntax.

\newcommand{\rep}[1]{{#1}^{#1}_{#1}}
\newcommand{\rrep}[2]{%
\ifnum#1>0
\expandafter\rrep\expandafter{\number\numexpr#1-1\relax}{\rep{#2}}%
\else
#2%
\fi
}
\(\rrep{3}{\int}\)
\newcommand\unions[2]{
\ifnum#1>1 {#2}_{#1} \cup \expandafter\unions\expandafter{\number\numexpr#1-1\relax}{#2}
\else
{#2}_1
\fi
}
$\unions{6}{S}$
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment