10

I have been experimenting with the \newif construction in plain \TeX. To keep my experiments from clashing with plain \TeX, I changed the definition slightly to

\outer\def\znewif#1{\count255=\escapechar \escapechar=-1 \expandafter\expandafter\expandafter \edef\zif#1{true}{\let\noexpand#1=\noexpand\iftrue}% \expandafter\expandafter\expandafter \edef\zif#1{false}{\let\noexpand#1=\noexpand\iffalse}% \zif#1{false}\escapechar=\count255} % the condition starts out false \def\zif#1#2{\csname\expandafter\ifz\string#1#2\endcsname} {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\ifz12{}}} 

It seemed to me that \edefs could be changed to \defs if I omitted the \noexpands. I made the changes, as follows,

\outer\def\znewif#1{\count255=\escapechar \escapechar=-1 \expandafter\expandafter\expandafter \def\zif#1{true}{\let#1=\iftrue}% \expandafter\expandafter\expandafter \def\zif#1{false}{\let#1=\iffalse}% \zif#1{false}\escapechar=\count255} % the condition starts out false \def\zif#1#2{\csname\expandafter\ifz\string#1#2\endcsname} {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\ifz12{}}} 

and it worked the same way, and

\znewif\ifalpha {\tt\meaning\ifalpha} {\tt\meaning\alphatrue} {\tt\meaning\alphafalse} 

gives the same output. So why does the definition of \newif use \edef and \noexpand?

5
  • 1
    The definition of \newif given in plain.tex does use \def. Where did you find this \edef version? Commented Aug 16 at 2:44
  • 1
    From The TeXBook, page 348 (Appendix B: Basic Control Sequences), the e-book version that can be found online. Your comment urged me to try \show\newif, and it does say \def. Now I wonder what my hard copy book would say if I dug it out and looked. If it says \def, serves me right for being lazy. Commented Aug 16 at 3:13
  • 1
    I did check my hard copy. It says \edef too. But the texlive distribution is using \def. It must be something that got cleaned up after The TeXBook was published. Commented Aug 16 at 3:28
  • You may have "unearthed" one of several differences between "Knuth TeX" (which, probably unsurprisingly, is what Knuth presents in The TeXBook) and eTeX ("extended TeX"). The latter is what's used in (nearly) all current versions of Plain-TeX. Commented Aug 16 at 3:48
  • My edition of the TeXbook (2021) also has \def instead of \edef. This is in the CTAN texbook.tex as well. Commented Aug 16 at 5:46

1 Answer 1

6

No reason, because \newif doesn't use \edef.

The main purpose of \newif\iffoo is to define \footrue and \foofalse that stand for

\let\iffoo\iftrue \let\iffoo\iffalse 

respectively and to issue \foofalse. A secondary purpose is to only allow \newif\if<other letters>.

Actually Knuth relies on users not trying \newif\if, which is syntactically valid and redefines \if to be (initially) \iffalse and also defines \true and \false.

\outer\def\newif#1{\count@\escapechar \escapechar\m@ne \expandafter\expandafter\expandafter \def\@if#1{true}{\let#1=\iftrue}% \expandafter\expandafter\expandafter \def\@if#1{false}{\let#1=\iffalse}% \@if#1{false}\escapechar\count@} % the condition starts out false \def\@if#1#2{\csname\expandafter\if@\string#1#2\endcsname} {\uccode`1=`i \uccode`2=`f \uppercase{\gdef\if@12{}}} % `if' is required 

You apparently found an edition of the TeXbook prior to 1998, because we find in errata.ten

\bugonpage A348, lines 14--16 (8/6/98) \ninepoint\noindent | \def\@if#1{true}{\let#1=\iftrue}%|\par\noindent | \expandafter\expandafter\expandafter|\par\noindent | \def\@if#1{false}{\let#1=\iffalse}%|\par\noindent 

The “bug” is that

 \expandafter\expandafter\expandafter \edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}% 

is completely equivalent to the standard definition in plain.tex, because \let and = aren't expandable.

Quite likely \edef was a leftover of times when conditionals were treated differently.

Have a look at the following interactive TeX session transcript:

This is TeX, Version 3.141592653 (TeX Live 2025) (preloaded format=tex) **\relax *\def\abc{abc}\def\foo{\abc}\edef\baz{\noexpand\abc} *\ifx\foo\baz\message{EQUAL}\else\message{DIFFERENT}\fi EQUAL *\end No pages of output. Transcript written on texput.log. 
4
  • 2
    older copies of the texbook do have \edef\@if#1{true}{\let\noexpand#1=\noexpand\iftrue}% looking at some pdf that are to be found in dubious places Commented Aug 16 at 10:12
  • @DavidCarlisle Thanks. I modified accordingly. Commented Aug 16 at 10:32
  • 5
    The change is mentioned in errata.ten. It's dated `(8/6/98)'. Commented Aug 16 at 11:32
  • @UdoWermuth My search skills aren't as good as yours! Commented Aug 16 at 13:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.