Blog

Understanding xii.tex

In December 1998, David Carlisle posted the following to comp.text.tex:

\let~\catcode~`76~`A13~`F1~`j00~`P2jdefA71F~`7113jdefPALLF
PA''FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA&&71jfi
Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
:76jelse&U76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
I71Fo71dPA!!FRgiePBt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye

It was also published in TUGboat as A Seasonal Puzzle, and is also available on CTAN as xii.

Put this code in a file called xii.tex and run

pdftex xii.tex

to get xii.pdf.

How is it doing this; what’s going on here?

Let’s start at the beginning, reading the input the way TeX would. The file starts: \let~\catcode. In TeX, the primitive command \let assigns to the active character ~ the meaning of \catcode (whatever that means: we’ll see shortly). In other words: from now on, ~ means \catcode. So this is the rest of the input, with ~ replaced with \catcode:

\catcode`76\catcode`A13\catcode`F1\catcode`j00\catcode`P2jdefA71F\catcode`7113jdefPALLF
PA''FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA&&71jfi
Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
:76jelse&U76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
I71Fo71dPA!!FRgiePBt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye

This may not seem like an improvement, but things will become clearer. In TeX, every character has a category code and \catcode sets the category code. Here, the first line sets:

The first line with some line breaks for clarity:

\catcode`76
\catcode`A13
\catcode`F1
\catcode`j0
\catcode`P2
jdefA71F\catcode`7113jdefP
ALLF
PA''FwPA;;FPAZZFLaLPA//71F71iPAHHFLPAzzFenPASSFthP;A$$FevP
A@@FfPARR717273F737271P;ADDFRgniPAWW71FPATTFvePA**FstRsamP
AGGFRruoPAqq71.72.F717271PAYY7172F727171PA??Fi*LmPA&&71jfi
Fjfi71PAVVFjbigskipRPWGAUU71727374 75,76Fjpar71727375Djifx
:76jelse&U76jfiPLAKK7172F71l7271PAXX71FVLnOSeL71SLRyadR@oL
RrhC?yLRurtKFeLPFovPgaTLtReRomL;PABB71 72,73:Fjif.73.jelse
B73:jfiXF71PU71 72,73:PWs;AMM71F71diPAJJFRdriPAQQFRsreLPAI
I71Fo71dPA!!FRgiePBt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
doTsW,Wk;Rri@stW aHAHHFndZPpqar.tridgeLinZpe.LtYer.W,:jbye

If we undo some of this catcode-obfuscation, namely:

this becomes:

\def~#1{\catcode`#113\def}
~LL{
}~''{w}~;;{}~ZZ{LaL}~//#1{#1i}~HH{L}~zz{en}~SS{th};~$${ev}
~@@{f}~RR#1#2#3{#3#2#1};~DD{Rgni}~WW#1{}~TT{ve}~**{stRsam}
~GG{Rruo}~qq#1.#2.{#1#2#1}~YY#1#2{#2#1#1}~??{i*Lm}~&&#1\fi
{\fi#1}~VV{\bigskipR}WG~UU#1#2#3#4 #5,#6{\par#1#2#3#5D\ifx
:#6\else&U#6\fi}L~KK#1#2{#1l#2#1}~XX#1{VLnOSeL#1SLRyadR@oL
RrhC?yLRurtK{eL}{ov}gaTLtReRomL;}~BB#1 #2,#3:{\if.#3.\else
B#3:\fiX{#1}U#1 #2,#3:}Ws;~MM#1{#1di}~JJ{Rdri}~QQ{RsreL}~I
I#1{o#1d}~!!{Rgie}Bt'el@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqs'.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.'oL.Rtrul;e
doTsW,Wk;Rri@stW aH~HH{ndZ}pqar.tridgeLinZpe.LtYer.W,:\bye

The first \def command defines ~ which makes the next character active, and then starts a \def. So for example the

~''{w}

means

\catcode`'=13
\def'{w}

i.e. it defines ' as w. Let’s replace it everywhere:

\def~#1{\catcode`#113\def}
~LL{
}~;;{}~ZZ{LaL}~//#1{#1i}~HH{L}~zz{en}~SS{th};~$${ev}
~@@{f}~RR#1#2#3{#3#2#1};~DD{Rgni}~WW#1{}~TT{ve}~**{stRsam}
~GG{Rruo}~qq#1.#2.{#1#2#1}~YY#1#2{#2#1#1}~??{i*Lm}~&&#1\fi
{\fi#1}~VV{\bigskipR}WG~UU#1#2#3#4 #5,#6{\par#1#2#3#5D\ifx
:#6\else&U#6\fi}L~KK#1#2{#1l#2#1}~XX#1{VLnOSeL#1SLRyadR@oL
RrhC?yLRurtK{eL}{ov}gaTLtReRomL;}~BB#1 #2,#3:{\if.#3.\else
B#3:\fiX{#1}U#1 #2,#3:}Ws;~MM#1{#1di}~JJ{Rdri}~QQ{RsreL}~I
I#1{o#1d}~!!{Rgie}Btwel@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsZ.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasZ.ilk,%
s$;z zLqsw.ansZ.Ymi,/sx ;LYegseZRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.woL.Rtrul;e
doTsW,Wk;Rri@stW aH~HH{ndZ}pqar.tridgeLinZpe.LtYer.W,:\bye

The ~ZZ{LaL} defines Z as LaL, so let’s replace that:

\def~#1{\catcode`#113\def}
~LL{
}~;;{}~//#1{#1i}~HH{L}~zz{en}~SS{th};~$${ev}
~@@{f}~RR#1#2#3{#3#2#1};~DD{Rgni}~WW#1{}~TT{ve}~**{stRsam}
~GG{Rruo}~qq#1.#2.{#1#2#1}~YY#1#2{#2#1#1}~??{i*Lm}~&&#1\fi
{\fi#1}~VV{\bigskipR}WG~UU#1#2#3#4 #5,#6{\par#1#2#3#5D\ifx
:#6\else&U#6\fi}L~KK#1#2{#1l#2#1}~XX#1{VLnOSeL#1SLRyadR@oL
RrhC?yLRurtK{eL}{ov}gaTLtReRomL;}~BB#1 #2,#3:{\if.#3.\else
B#3:\fiX{#1}U#1 #2,#3:}Ws;~MM#1{#1di}~JJ{Rdri}~QQ{RsreL}~I
I#1{o#1d}~!!{Rgie}Btwel@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsLaL.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasLaL.ilk,%
s$;z zLqsw.ansLaL.Ymi,/sx ;LYegseLaLRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.woL.Rtrul;e
doTsW,Wk;Rri@stW aH~HH{ndLaL}pqar.tridgeLinLaLpe.LtYer.W,:\bye

Adding some line breaks (and replacing some of them with a space) gives:

\def~#1{\catcode`#113\def}
~LL{ }
~;;{}
~//#1{#1i}
~HH{L}
~zz{en}
~SS{th};
~$${ev}
~@@{f}
~RR#1#2#3{#3#2#1};
~DD{Rgni}
~WW#1{}
~TT{ve}
~**{stRsam}
~GG{Rruo}
~qq#1.#2.{#1#2#1}
~YY#1#2{#2#1#1}
~??{i*Lm}
~&&#1\fi{\fi#1}
~VV{\bigskipR}
WG~UU#1#2#3#4 #5,#6{\par#1#2#3#5D\ifx :#6\else&U#6\fi}
L~KK#1#2{#1l#2#1}
~XX#1{VLnOSeL#1SLRyadR@oL RrhC?yLRurtK{eL}{ov}gaTLtReRomL;}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
Ws;
~MM#1{#1di}
~JJ{Rdri}
~QQ{RsreL}
~II#1{o#1d}
~!!{Rgie}
Btwel@ lTLqdrYmu.Q.,Ke;vz vzLqpip.Q.,tz;
;Lql.IrsLaL.eap,qn.i. i.eLlMaesLdRcna,;!;h htLqm.MRasLaL.ilk,%
s$;z zLqsw.ansLaL.Ymi,/sx ;LYegseLaLRyal,@i;@ TLRlogdLrDsW,@;G
LcYlaDLbJsW,SWXJW ree @rzchLhzsW,;WERcesInW qt.woL.Rtrul;e
doTsW,Wk;Rri@stW aH~HH{ndLaL}pqar.tridgeLinLaLpe.LtYer.W,:
\bye

We can start doing some of the replacements. For example, L is defined as a space, so we can replace L with a space in most places, but some of those are “load-bearing” and we can’t replace just yet. Simiarly, ; is defined as {} so we can remove it entirely in some places and replace it with {} in others, but in some places it’s still needed. ~//#1{#1i} defines / as appending an i to whatever token comes next, and it’s used in only one place, where /sx means six. The letter z just replaces en. The letter $ stands for ev. @ stands for f. D stands for Rgni (needs to be enclosed in a group—as {Rgni}—in one place before replacing). W just eats the next letter in a couple of places, but it’s doing something important in others! T stands for ve, as in gave and doves. V stands for \bigskipR. M appends di, as in lMaes -> ladies. J stands for Rdri, whatever that means. And some more things like that.

\def~#1{\catcode`#113\def}
~LL{ }
~;;{}
~HH{ }
~SS{th}
~RR#1#2#3{#3#2#1}
~WW#1{}
~qq#1.#2.{#1#2#1}
~YY#1#2{#2#1#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{Rgni}\ifx :#6\else&U#6\fi}
~KK#1#2{#1l#2#1}
~XX#1{\bigskipRLnOthe #1S RyadRfoL RrhCistRsam my RurtK{e }{ov}gave tReRomL}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
~QQ{RsreL}
~II#1{o#1d}
~!!{Rgie}
Btwelf l{ve} qdrYmu.Q.,Ke;ven ven qpip.Q.,ten;
{} ql.Irs a .eap,qn.i. i.e ladies dRcna,;!{}h ht qm.Rdias a .ilk,%
seven en qsw.ans a .Ymi,six {} Yegse a Ryal,fi{}f ve Rlogd rRgnisW,f{}{Rruo}
LcYlaRgni bRdrisW,SWXRdriW ree french hensW,;WERcesInW qt.wo .Rtrule
dovesW,Wk{}RrifstW aH~HH{nd a }pqar.tridge in a pe. tYer.W,:
\bye

Actually, note the definition

~RR#1#2#3{#3#2#1}

here R just reverses the next three arguments, e.g. Rgni is ing, and

RLnOthe #1S RyadRfoL RrhCistRsam my RurtK{e }{ov}gave tReRomL

is (well, not exactly—note the recursion towards the end—but in this case):

 OnLthe #1S dayLof Christmas my truK{e }{ov}gave to me

With those replacements, and some further Ls replaced with spaces:

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~YY#1#2{#2#1#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{ing}\ifx :#6\else&U#6\fi}
~KK#1#2{#1l#2#1}
~XX#1{\bigskip On the #1S day of Christmas my truK{e }{ov}gave to me}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
~QQ{ers }
~II#1{o#1d}
~!!{eig}
Btwelf l{ve} qdrYmu.Q.,Ke;ven ven qpip.Q.,ten;
{} ql.Irs a .eap,qn.i. i.e ladies danc,;!{}h ht qm.aids a .ilk,%
seven en qsw.ans a .Ymi,six {} Yegse a lay,fi{}f ve gold ringsW,f{}{our}
{ }cYlaing birdsW,SWXirdW ree french hensW,;WEsecInW qt.wo .urtle
dovesW,Wk{}firstW aH~HH{nd a }pqar.tridge in a pe. tYer.W,:
\bye

We can further replace Q with ers and the definition Y#1#2{#2#1#1} which means that drYmu.ers is drumm.ers; Ymi is imm; Yegse is geese; cYlaing is calling; tYer is tree, and the definition I#1{o#1d} which means that l.Irs is l.ords and secIn is second, and replace ! with eig:

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{ing}\ifx :#6\else&U#6\fi}
~KK#1#2{#1l#2#1}
~XX#1{\bigskip On the #1S day of Christmas my truK{e }{ov}gave to me}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
Btwelf l{ve} qdrumm.ers .,Ke;ven ven qpip.ers .,ten;
{} ql.ords a .eap,qn.i. i.e ladies danc,;{eig}{}h ht qm.aids a .ilk,%
seven en qsw.ans a .imm,six {} geese a lay,fi{}f ve gold ringsW,f{}{our}
{ }calling birdsW,SWXirdW ree french hensW,;WEsecondW qt.wo .urtle
dovesW,Wk{}firstW aH~HH{nd a }pqar.tridge in a pe. tree.W,:
\bye

The first nontrivial compression is effected by

~qq#1.#2.{#1#2#1}

which for example lets us replace:

so (turns out we cannot replace qn.i. with nin, for reasons we’ll hopefully see later):

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{ing}\ifx :#6\else&U#6\fi}
~KK#1#2{#1l#2#1}
~XX#1{\bigskip On the #1S day of Christmas my truK{e }{ov}gave to me}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
Btwelf lve drummers drumm,Ke;ven ven pipers pip,ten;
{} lords a leap,qn.i. i.e ladies danc,;{eig}{}h ht maids a milk,%
seven en swans a swimm,six {} geese a lay,fi{}f ve gold ringsW,f{}{our}
{ }calling birdsW,SWXirdW ree french hensW,;WEsecondW two turtle
dovesW,Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,:
\bye

Similarly, the ~KK#1#2{#1l#2#1} definition is quite local:

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{ing}\ifx :#6\else&U#6\fi}
~XX#1{\bigskip On the #1S day of Christmas my true love gave to me}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
Btwelf lve drummers drumm,eleven ven pipers pip,ten;
{} lords a leap,qn.i. i.e ladies danc,;{eig}{}h ht maids a milk,%
seven en swans a swimm,six {} geese a lay,fi{}f ve gold ringsW,f{}{our}
{ }calling birdsW,SWXirdW ree french hensW,;WEsecondW two turtle
dovesW,Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,:
\bye

The rest is not so trivial. For example, B:

~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}

this is recursive (note the B in its definition), but in the document is directly invoked only once at the end (like a main()), with

#1<-twelf
#2<-lve drummers drumm
#3<-eleven ven pipers pip,ten; {} lords a leap,qn.i. i.e ladies danc,;{eig}{}h ht maids a milk,seven en swans a swimm,six {} geese a lay,fi{}f ve gold ringsW,f{}{our} { }calling birdsW,SWXirdW ree french hensW,;WEsecondW two turtle dovesW,Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,

With some line-breaks added for clarity (the end-of-line comments are needed, to comment out the line break):

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{\par#1#2#3#5{ing}\ifx :#6\else&U#6\fi}
~XX#1{\bigskip On the #1S day of Christmas my true love gave to me}
~BB#1 #2,#3:{\if.#3.\else B#3:\fiX{#1}U#1 #2,#3:}
B%
twelf lve drummers drumm,%
eleven ven pipers pip,%
ten {} lords a leap,%
qn.i. i.e ladies danc,%
;{eig}{}h ht maids a milk,%
seven en swans a swimm,%
six {} geese a lay,%
fi{}f ve gold ringsW,%
f{}{our} { }calling birdsW,%
SWXirdW ree french hensW,%
;WEsecondW two turtle dovesW,%
Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,:
\bye

It would be easier to start with the final document and explain how it can be compressed to this. :-)

In short: B is a recursive macro that first calls B on its third argument (typesetting the corresponding paragraphs), then typesets the current paragraph. U is a recursive macro that first typeset’s the current day’s gift, then typesets earlier days' gifts. In case it helps:

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{
    \par
    % This day's gift
    #1#2#3#5{ing}
    \ifx :#6
    \else
        % The earlier days' gifts
        &U#6
    \fi
}
~BB#1 #2,#3:{
    % Recursively typeset earlier paragraphs if any.
    \if.#3.
    \else
        B#3:
    \fi
    % Now typeset the current paragraph.
    \bigskip On the #1S day of Christmas my true love gave to me
    U#1 #2,#3:
}
B%
twelf lve drummers drumm,%
eleven ven pipers pip,%
ten {} lords a leap,%
qn.i. i.e ladies danc,%
;{eig}{}h ht maids a milk,%
seven en swans a swimm,%
six {} geese a lay,%
fi{}f ve gold ringsW,%
f{}{our} { }calling birdsW,%
SW?irdW ree french hensW,%
;WEsecondW two turtle dovesW,%
Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,:
\bye

In the spirit of “You Could Have Invented…” (as in You Could Have Invented Spectral Sequences and You Could Have Invented Monads! (And Maybe You Already Have.)), here’s a just-so story of how you could arrive at the above.

First, consider the most straightforward way of producing the desired output:

\bigskip On the first day of Christmas my true love gave to me
\par a partridge in a pear tree.

\bigskip On the second day of Christmas my true love gave to me
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the third day of Christmas my true love gave to me
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the fourth day of Christmas my true love gave to me
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the fifth day of Christmas my true love gave to me
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the sixth day of Christmas my true love gave to me
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the seventh day of Christmas my true love gave to me
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the eighth day of Christmas my true love gave to me
\par eight maids a milking
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the ninth day of Christmas my true love gave to me
\par nine ladies dancing
\par eight maids a milking
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the tenth day of Christmas my true love gave to me
\par ten lords a leaping
\par nine ladies dancing
\par eight maids a milking
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the eleventh day of Christmas my true love gave to me
\par eleven pipers piping
\par ten lords a leaping
\par nine ladies dancing
\par eight maids a milking
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bigskip On the twelfth day of Christmas my true love gave to me
\par twelve drummers drumming
\par eleven pipers piping
\par ten lords a leaping
\par nine ladies dancing
\par eight maids a milking
\par seven swans a swimming
\par six geese a laying
\par five gold rings
\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

\bye

Now let’s say we wanted to write this more concisely. There are basically a quadratically-growing number of lines, so we need two loops. For the list of gifts, to expand to something like:

\par four calling birds
\par three french hens
\par two turtle doves
\par and a partridge in a pear tree.

we need a macro, say \gifts, such that, say,

\gifts four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

expands to the above. We can write this as:

\def\gifts#1,#2.{
    \par #1%
    % If #2 is empty, then output just the final '.'
    \ifx\relax#2\relax
        .
    \else
        \gifts #2.
    \fi
}

\bigskip On the first day of Christmas my true love gave to me
\gifts a partridge in a pear tree,.

\bigskip On the second day of Christmas my true love gave to me
\gifts two turtle doves, and a partridge in a pear tree,.

\bigskip On the third day of Christmas my true love gave to me
\gifts three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the fourth day of Christmas my true love gave to me
\gifts four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the fifth day of Christmas my true love gave to me
\gifts five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the sixth day of Christmas my true love gave to me
\gifts six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the seventh day of Christmas my true love gave to me
\gifts seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the eighth day of Christmas my true love gave to me
\gifts eight maids a milking, seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the ninth day of Christmas my true love gave to me
\gifts nine ladies dancing, eight maids a milking, seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the tenth day of Christmas my true love gave to me
\gifts ten lords a leaping, nine ladies dancing, eight maids a milking, seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the eleventh day of Christmas my true love gave to me
\gifts eleven pipers piping, ten lords a leaping, nine ladies dancing, eight maids a milking, seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bigskip On the twelfth day of Christmas my true love gave to me
\gifts twelve drummers drumming, eleven pipers piping, ten lords a leaping, nine ladies dancing, eight maids a milking, seven swans a swimming, six geese a laying, five gold rings, four calling birds, three french hens, two turtle doves, and a partridge in a pear tree,.

\bye

This hasn’t saved us much typing (just the \par, more or less), but it prepares us to write a \verses for the recursion. This takes some care, but this works:

\def\gifts#1 #2,#3.{
    \par #2%
    % If #3 is empty, then output just the final '.'
    \if\relax#3\relax
        .
    \else
        \gifts #3.
    \fi
}

\def\verses#1 #2,#3.{
    % All the earlier verses.
    \if\relax#3\relax
    \else
        \verses #3.
    \fi
    \bigskip On the #1 day of Christmas my true love gave to me
    \gifts #1 #2,#3.
}

\def\prefix{}
    
\verses
twelfth twelve drummers drumming,%
eleventh eleven pipers piping,%
tenth ten lords a leaping,%
ninth nine ladies dancing,%
eighth eight maids a milking,%
seventh seven swans a swimming,%
sixth six geese a laying,%
fifth five gold rings,%
fourth four calling birds,%
third three french hens,%
second two turtle doves,%
first \prefix\def\prefix{and }a partridge in a pear tree,.

\bye

Note the trick where we print just a partridge in a pear tree the first time, but thereafter define \prefix to be and so that we print and a partridge in a pear tree all future times.

Further tricks to factor out the common th (twelfth -> twelve and so on, noticing that we need to do something different for second -> two for example), and also one standard TeX trick / best practice to keep stack bounded during recursion (the \fi trick), would give us something like the version we had earlier:

\def~#1{\catcode`#113\def}
~;;{}
~HH{ }
~SS{th}
~WW#1{}
~qq#1.#2.{#1#2#1}
~&&#1\fi{\fi#1}
~UU#1#2#3#4 #5,#6{
    \par
    % This day's gift
    #1#2#3#5{ing}
    \ifx :#6
    \else
        % The earlier days' gifts
        &U#6
    \fi
}
~BB#1 #2,#3:{
    % Recursively typeset earlier paragraphs if any.
    \if.#3.
    \else
        B#3:
    \fi
    % Now typeset the current paragraph.
    \bigskip On the #1S day of Christmas my true love gave to me
    U#1 #2,#3:
}
B%
twelf lve drummers drumm,%
eleven ven pipers pip,%
ten {} lords a leap,%
qn.i. i.e ladies danc,%
;{eig}{}h ht maids a milk,%
seven en swans a swimm,%
six {} geese a lay,%
fi{}f ve gold ringsW,%
f{}{our} { }calling birdsW,%
SW?irdW ree french hensW,%
;WEsecondW two turtle dovesW,%
Wk{}firstW aH~HH{nd a }partridge in a pear tree.W,:
\bye

Two more things to mention: