2

If I write

\count10=\iftrue'\fi10 \the\count10

then the answer is 8, because the "if" clause adds a ' which causes 10 to be interpreted as octal.

If I write this, the answer is also 8:

\count10='\iftrue\fi10
\the\count10

However, if I switch out the "if" clause for a different expandable-- say, \relax:

\count10='\relax10
\the\count10

then it fails:

! Missing number, treated as zero.
<to be read again> 
                   \relax 
l.16 \count10='\relax
                     10

What makes the difference?

5
  • well \relax stops the parsing for a number, you would get a similar error if you put x there. May 24, 2023 at 17:59
  • @UlrikeFischer is that a special property of \relax, then, and I just happened to pick the expandable that didn't work like the if clause? May 24, 2023 at 18:01
  • 1
    ??? \relax is the "most popular" nonexpandable command though? (in the sense that its only purpose to exist is to be unexpandable) If you try \empty it would work.
    – user202729
    May 24, 2023 at 18:27
  • 3
    Well, now I feel a bit of a numpty! May 24, 2023 at 18:46
  • @MarnanelThurman ... if you want to get more confused, take at look at my 2006 (sic!) TeX Pearl "\relax ex machina II" ( gust.org.pl/projects/pearls/2006p/bernd-raichle/… ): you can browse through TeX.web, the source code of TeX, to find these unusual places at which TeX will ignore = read over a \relax token. Jul 2, 2023 at 15:04

1 Answer 1

3

There are contexts where \relax is ignored during the scan for the argument to a primitive command, but this is not one of them.

The TeXbook defines a ⟨filler⟩ as any sequence of space and \relax tokens; when it is scanning for {, a ⟨filler⟩ is ignored. Note, however that the TeXbook uses { to denote an explicit or implicit character token of category code 1. So a ⟨filler⟩ is ignored when looking for the argument in a token register assignment or in a \lowercase operation (see Get the lion to run in loops. Tersely for a peculiar aspect).

Another case when \relax is ignored is when it is used for ending an expression to be passed to \numexpr, \dimexpr, \glueexpr or \muexpr.

When TeX wants to determine the argument for an assignment to a \count register, it looks for an optional = and then expands tokens (if expandable, of course) as long as it finds something that can be interpreted as an integer (which may include a prefix for the radix). At the first token that cannot be interpreted as valid input for a number in the chosen radix, the search stops and the number is evaluated for storing.

Important exception: when TeX has determined that an integer is in alphabetic format, that is, when the prefix is ` (backquote), it stops expanding tokens and takes the next character token or length one control sequence to be the alphabetic constant, translating it into ASCII code (or Unicode, for Unicode engines). An error would be raised if the input is incorrect.

Let's examine your attempts

\count10=\iftrue'\fi10 \the\count10
\count10='\iftrue\fi10 \the\count10
\count10='\relax10

In the first case TeX finds something expandable after = and expands it. Well, the expansion of \iftrue is empty and then ' is scanned because it's part or the “true text”; now TeX knows that it wants to look for an octal constant. Next it finds \fi, whose expansion is empty and next 1, then 0 and finally a space that ends the scanning process. The number is computed and the value stored in the register; the space is ignored and processing continues, in this case printing the value stored in the register.

The second case is completely similar. But the third one has a problem: after ' there's \relax that's not ignored. It is an unexpandable token that cannot be interpreted as an octal digit and TeX stops with an error, because just the radix prefix is not a valid number.

Out of curiosity, here's another case that fails:

\chardef\foo=10
\count10='\foo

A \chardef token can be used in the context of a number, but not with a radix prefix: it is an “abstract” number, just like in

\count10=\count255

The prefixes ' and " can only be used in front of an explicit number, that is, a sequence of digits in the appropriate range.

3
  • Thank you! That was a very comprehensive and helpful answer. May 24, 2023 at 22:47
  • In the case of \numexpr saying "ignore" may not be the most accurate description, as it gobbles exactly one \relax -- if there are two \relax they won't be "ignored" the same way.
    – user202729
    May 25, 2023 at 8:47
  • @user202729 Did I say that you can use any number of \relax tokens?
    – egreg
    May 25, 2023 at 9:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .