9

Exercise 5.6 of the TeXbook by Knuth reads:

If you think you understand local and global definitions, here's a little test to make sure: Suppose \c stands for \count1=, \g stands for \global\count1=, and \s stands for \showthe\count1. What values will be shown?

{\c1\s\g2{\s\c3\s\g4\s\c5\s}\s\c6\s}\s

When I tried to follow this in my mind and enter the "expanded" form, I came up with:

{\count1=1\showthe\count1\global\count1=2{\showthe\count1\count1=3\showthe\count1\global\count1=4\showthe\count1\count1=5\showthe\count1}\showthe\count1\count1=6\showthe\count1}\showthe\count1

But this gives me an error. Here is a more readable version of the whole exercise:

{% outer block
\count1=1%
\showthe\count1%
\global\count1=2%
{% inner block
\showthe\count1%
\count1=3%
\showthe\count1%
\global\count1=4%
\showthe\count1%
\count1=5%
\showthe\count1%
}%
\showthe\count1%
\count1=6%
\showthe\count1%
}%
\showthe\count1

Prediction:

1 2 3 4 5 4 6 4

\end

The error is:

$ tex chapter5.tex 
This is TeX, Version 3.14159265 (TeX Live 2017/Debian) (preloaded format=tex)
(./chapter5.tex
> 1.
<to be read again> 
                   \global 
l.4 \global
           \count1=2%
? 

Note: I don't know if I overdid with the trailing %, but better safe than sorry ;)

What's going on here? Or is this perhaps the point, after all, that TeX prevents me from shadowing a previously assigned local variable by assignment of a global one with the same name?

btw: my guess was 1 2 3 4 5 4 6 4, but I cannot verify that result. I know this is rated two "dangerous bends" and this is my first reading of TeXbook, but I found it intriguing and so decided to give it a try.

7
  • 2
    There is no error. The code prints nothing, it just makes TeX to stop at each \showthe command.
    – egreg
    Apr 9 '20 at 8:22
  • 2
    Yes, that’s it.
    – egreg
    Apr 9 '20 at 8:27
  • 1
    @0xC0000022L You can put the code in a file if you want. Either run it without any option and press Enter to continue every time you have a prompt, or compile it with -interaction=nonstopmode to have all the output in one go.
    – frougon
    Apr 9 '20 at 8:40
  • 1
    it doesn't matter here but it's a really bad idea to put a % at the end of a line such as \count1=6% it's not "better safe than sorry" it's a bug waiting to happen. If the following line had started with 1 rather than \showthe this would have set the value to 61 rather than 6. Apr 9 '20 at 8:57
  • 1
    This is due to the famous 〈one optional space〉 in the syntax for 〈normal integer〉 (see TeXbook p. 269).
    – frougon
    Apr 9 '20 at 10:19
11

The command \showthe will make TeX to stop for showing the value on the console. It uses the same mechanism as for displaying error messages, which is probably the reason why you thought to have made one.

The code would produce no output at all.

A version for printing the numbers:

\def\c{\count1=}
\def\g{\global\count1=}
\def\s{\relax\the\count1\space\space}
{\c1\s\g2{\s\c3\s\g4\s\c5\s}\s\c6\s}\s
\bye

enter image description here

Further exercise: why \relax and \space\space?

The \relax can also be \space; and \space\space could be \relax\space. If we expand the definitions, we get, in the first instance

\count1=1\relax\the\count1\space\space

or

\count1=1\relax\the\count1\relax\space

TeX will always look for a space after a constant (with macro expansion) and will then ignore it. Termination of constants is very important. Not in the first instance, actually, because this would be followed by \global that can't be interpreted as a number. But with \g4\s\c5, without \relax we'd get

\global\count1=4\the\count1

which would assign \count1 a different value, namely 43, because TeX will continue to expand \the.

The double \space in \s is meant to print a space between the numbers; the first \space would be ignored, the second one outputs a space. Using \relax ends the expansion as well, because \relax can't be interpreted as a digit.

5
  • \relax presumably for the same reason why % isn't always a good idea ... essentially we don't know what comes before the newly defined \s. Why \space\space and not just \space is beyond me, though (at least for now). Apr 9 '20 at 9:36
  • Just try it and you'll see! :-)
    – frougon
    Apr 9 '20 at 10:14
  • @frougon I did. \relax\space seems to be equivalent to \space\space (it would have been what I would have opted for), but \space and \space\relax don't work (no blank space in the output). But I still don't know why. My guess is that this is blank space that gets swallowed, but I don't understand the underlying mechanism (yet). Was I right regarding \relax though? Apr 9 '20 at 12:39
  • @0xC0000022L I added the explanation.
    – egreg
    Apr 9 '20 at 14:08
  • @frougon Fixed. 42 would have been better
    – egreg
    Apr 9 '20 at 14:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.