\let and \def differentiation in D. Knuth’s commentary (plain TeX)

definitionmacrosplain-tex

In the The TeX Book, in apendix B, I read

\def\obeyspaces{\catcode`\ =\active}
{\obeyspaces\global\let =\space}
{%
\catcode`\^^M=\active % these lines must end with ‘%’
\gdef\obeylines{\catcode`\^^M=\active \let^^M=\par}%    
\global\let^^M=\par % this is in case ^^M appears in a \write
} 

The \obeylines macro says ‘\let^^M=\par’ instead of ‘\def^^M{\par}’ because the
\let technique allows constructions such as ‘\let\par=\cr \obeylines \halign{…}’
in which \cr’s need not be given within the alignment.

But I don't get the suggested point in that comment. Could someone help me?

Best Answer

For (some) purposes, a primitive \halign needs to directly "see" the & and \cr tokens that end alignment cells. You can see the effect in LaTeX where some packages grabbing cell contents don't work so well in the last column, which ends with \\ (which is a macro with \cr in its definition) as opposed to other columns that end with & directly.

By using \let as described, the end result is that at the end of line TeX places an active character with meaning the \cr csname, and not an active character with a meaning that is a macro that expands to \cr.

The following example produces two alignments but if you change \iffalse to \iftrue a third attempt using the suggested definition with \def instead of \let is used, which fails.


\def\test#1{[#1]}

\halign{\hfil\test{#}\cr
aaa\cr
bb\cr
c\cr}

{\let\par\cr\obeylines%
\halign{\hfil\test{#}
aaa
bb
c
}}%


\iffalse % this doesn't work
{%
\catcode`\^^M=\active % these lines must end with ‘%’
\gdef\obeylines{\catcode`\^^M=\active \def^^M{\par}}%    
\global\def^^M{\par}% this is in case ^^M appears in a \write
} 

{\let\par\cr\obeylines%
\halign{\hfil\test{#}
aaa
bb
c
}}%

\fi
\bye
Related Question