summaryrefslogtreecommitdiff
path: root/usergrps/uktug/baskervi/4_1/fine.tex
blob: 4284f97ea916a2d5b5ec7b2b1d79108ef51e9ef8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
\author[Jonathan Fine]{Jonathan Fine\\\texttt{J.Fine@uk.ac.cam.pmms}}
\title{Back(s)lash}
\begin{Article}

Welcome to the first of a series of columns devoted to the subtleties
of programming \TeX.  The focus will be on the primitive commands and
low-level features of \TeX.  This column is devoted to \verb"\csname"
and to avoiding its side effects.

The reader might do well to begin by turning to [40].  (This means
page~40 of {\em The \TeX book}).  Exercise~7.7 on that page, and its
solution, describe a \verb"\ifundefined" macro.   
This macro has three shortcomings.  The first is that 
\begin{verbatim}
\ifundefined{relax}
\end{verbatim}
will come out to be true!  
The second is that
\begin{verbatim}
\ifundefined{xyz}
\end{verbatim}
will define \verb"\xyz" to be \verb"\relax", if \verb"\xyz" is not
defined.  This is often not what is wanted.
The third problem is that the process of defining \verb"\xyz" will,
if done within a group, add an item to the save stack [301].  This
can cause problems in processing \LaTeX\ documents which have a lot
of cross-references.

To see this, we will use introduce a macro
\begin{verbatim}
\def\typeshow #1%
{%
  \immediate\write 16
  {> \string #1 = \meaning #1.}%
}%
\end{verbatim}
which will log the meaning of a token for us.

Here are two extracts from a \verb".log" file, which record its
interactive use.
\begin{verbatim}
*{\expandafter\typeshow\csname xyz\endcsname}
> \xyz = \relax.
\end{verbatim}
Notice the braces to confine the redefinition of \verb"\xyz" to a
group.  This next example shows that \verb"\xyz" really is
\begin{verbatim}
*\typeshow\xyz
> \xyz = undefined.
\end{verbatim}
undefined.

When \verb"\csname" is performed within a group, any (local)
assignment it might perform will be restored when the group ends.  If
we can end the group {\it before\/} the \verb"\typeshow" is called,
then we will get the orginal, undefined, meaning.
Here is how to do it.
\begin{verbatim}
\begingroup
  \expandafter
\endgroup
\expandafter
\typeshow
\csname xyz\endcsname
\end{verbatim}
The group will begin.  The \verb"\expandafter"s will have
\verb"\csname" brought into operation.  When the \verb"\endcsname" is
reached, execution passes to the token after the first
\verb"\expandafter", which is the \verb"\endgroup".  This restores
the value of \verb"\xyz".  Now \verb"\typeshow" gets the token
\verb"\xyz", {\it with the meaning of  \verb"undefined"}.

Here is a lightly edited version of the log file for the above code,
entered interactively, with elaborations on the previous comments
interspersed.
\begin{verbatim}
*\begingroup
{\begingroup}
\end{verbatim}
Here the first line is entered, and acted upon.
\begin{verbatim}
*  \expandafter
{\expandafter}
\end{verbatim}
The primitive (and expandable) command \verb"\expandafter" is now
being processed.  It looks for the next token,
\begin{verbatim}
*\endgroup
\end{verbatim}
here it is, and then expands the one after, which is
\begin{verbatim}
*\expandafter
{\expandafter}
\end{verbatim}
which will again cause for a token to be read
\begin{verbatim}
*\typeshow
\end{verbatim}
here it is, and the one after is
\begin{verbatim}
*\csname xyz\endcsname
{\csname}
\end{verbatim}
which is now executed.  It will form a control sequence \verb"\xyz".
Execution now passes to the token after the first
\verb"\expandafter", which is:
\begin{verbatim}
{\endgroup}
{restoring \xyz=undefined}
\end{verbatim}
and {\it this has the desired effect of restoring the original value}.
The rest proceeds as before
\begin{verbatim}
\typeshow #1->\immediate \write 16 
  {> \string #1 = \meaning #1.}
#1<-\xyz 
> \xyz = undefined.
\end{verbatim}
which is what we want.

\noindent
{\bf Exercise 1.}
Obtain the same effect, but by using \verb"\aftergroup" to export the
token \verb"\xyz" out of the group.  Discuss the relative merits of
the two methods.

\noindent
{\bf Exercise 2.}
Write a macro which tests as to whether (the meaning of) a token is
expandable.  Consult [212--215].

\end{Article}