\iffalse Revised: 18 March 1994 14 March 1994 \fi \title{Backslash---About {\protect\tt\protect\string\def} and {\protect\tt\protect\string\let}} \author[Jonathan Fine]{Jonathan Fine\\\texttt{J.Fine@uk.ac.cam.pmms}} \begin{Article} \noindent Beginners to programming \TeX\ sometimes wonder as to the difference between \verb"\let" and \verb"\def". More exactly, how do the commands \begin{verbatim} \def\cs{a} \let\cs=a \end{verbatim} differ from each other. To understand this, we must know that the \TeX\ operates by processing \emph{tokens}. It is convenient here to divide tokens into three types: \begin{itemize} \item character token \item active character \item control symbol or sequence \end{itemize} of which the last two have the special property, that they may be assigned a meaning (and so are called \emph{assignable} or {\em control} tokens), while character tokens (excluding the active characters of course) have a fixed and unchanging meaning. These then are the tokens. Assignable tokens can be given a meaning, while character tokens have a fixed meaning. The other side of the coin is of course that tokens have meanings. The possible meanings for a token are more diverse. The list \begin{itemize} \item a letter \item an \lq{}other\rq{} character \item a \lq{}something\rq{} character, where \lq{}something\rq{} is \emph{begin group}, \emph{end group}, \emph{math shift}, \emph{alignment tab}, {\em superscript}, \emph{subscript} or \emph{space}. The above, together with active characters (which are assignable, and have no intrinsic meaning of their own) give all the character tokens which can appear in the stomach of \TeX. For more details see [37] (this means page~37 of \emph{The \TeX book}), and [39], Exercise~7.3. \item primitive commands (starred in the index to the \emph{\TeX book}) \end{itemize} gives some of the possibilities. There are others. The commands \verb"\font", \verb"\chardef", \verb"\mathchardef", \verb"\countdef" and so forth assign a meaning to an (assignable) token, which does not appear in the above list. Finally, there are macros. Macros have a parameter text and a replacement text. Typically, they are created by using the \verb"\def", \verb"\gdef", \verb"\edef" and \verb"\xdef" commands. The difference between the various \verb"\def" commands, which all produce a macro, is explained on pages [206] and [215--6]. Note that the macro does not carry as part of its meaning the type of command which was used to create it. Finally, so that every token has a meaning, there is a final possibility, which is that the meaning is \verb"undefined". It is now possible to explain, at least in theoretical terms, the difference between \verb"\def" and \verb"\let". The execution of a \verb"\def" command will assign a macro meaning to a control sequence. Thus, \begin{verbatim} \def\cs{a} \end{verbatim} will produce a zero parameter macro \verb"\cs", whose parameter text is empty and whose replacement text is the single letter \verb"a". This can be seen by now applying the \verb"\show" command. \begin{verbatim} *\show\cs > \cs=macro: ->a. \end{verbatim} The \verb"\let" command, however, is used to transfer (or more exactly make a copy or reference to) an existing meaning. Thus, \begin{verbatim} \let\cs=a \end{verbatim} will produce a control sequence whose meaning is \begin{verbatim} *\show\cs > \cs=the letter a. \end{verbatim} the letter \verb"a". {\em This is not the same as the macro whose replacement text is the letter\/ \verb"a"}. So how do \verb"\def" and \verb"\let" differ? Well, \verb"\def" will always create a macro, while \verb"\let" will transfer a meaning. If we have already performed \begin{verbatim} \def\aaa{aaaaaaaaaa} \end{verbatim} then \begin{verbatim} \def\xyz{aaaaaaaaaa} \end{verbatim} will create a new macro \verb"\xyz" whose meaning happens to be the same as that of \verb"\aaa", while \begin{verbatim} \let\xyz\aaa \end{verbatim} will give to \verb"\xyz" the current meaning of \verb"\aaa", which happens to be \begin{verbatim} *\show\aaa > \aaa=macro: ->aaaaaaaaaa. \end{verbatim} but could have been otherwise. This use of \verb"\let" does not change the meaning of \verb"\aaa". Here \verb"\aaa" was a macro, but it could have had any meaning, perhaps even \verb"undefined". If one finds oneself making definitions such as \begin{verbatim} \def\cs{\token} \end{verbatim} where \verb"\token" is a single control sequence or character token, perhaps one should instead be using \begin{verbatim} \let\cs\token \end{verbatim} which will have the same effect, but more efficiently, in most contexts. However, there is a significant difference. When \verb"\let" is used, \verb"\cs" gets \emph{the current meaning} of \verb"\token" (which may not yet be defined). When \verb"\def" is used, \verb"\cs" is a macro which expands to \verb"\token" and so it is the meaning of \verb"\token" \emph{at the time of the use of} \verb"\cs" which is relevant. See [206--7] and especially Exercise~20.8, and also the definition of \verb"\obeylines" [352]. This nuance does not apply when \verb"\token" is given a fixed meaning, once and for all time. Finally, the answers to the exercises in the last issue, and a new exercise. \noindent {\bf Solution 1.} {\em Use \verb"\aftergroup" to export the token \verb"\xyz" out of the group, and discuss merits}. \begin{verbatim} \beinggroup \aftergroup\typeshow \expandafter \aftergroup\csname xyz\endcsname \endgroup \end{verbatim} This code is slower and bulkier than use of multiple \verb"\expandafter"s (as in the last issue) but will be quicker and more powerful if one wishes to assemble longer sequences of unusual tokens. \noindent {\bf Solution 2.} \emph{Write a macro which tests as to whether (the meaning of) a token is expandable}. According to the recommended pages [212--215], macros and \lq{}certain special primitives like \verb"\number" and \verb"\if"\rq{} are expanded. Reading on to the foot of [213] we find that \verb"\noexpand" applied to a token has expansion \lq{}the token itself; but that token is interpreted as if its meaning were \lq\verb"\relax"\rq{} if it is a control sequence that would ordinarily be expanded by \TeX\rq{}s expansion rules.\rq{} This change of interpretation is purely temporary, and holds only during the execution or expansion of the next command. The meaning then reverts to the original value. (I have not found a reference for this in the \emph{\TeX book}). Here then is the solution. It will not do to compare \verb"\noexpand #1" with \verb"\relax", for this fails when \verb"#1" is \verb"\relax". Instead, we test to see if applying \verb"\noexpand" to the parameter \verb"#1" \emph{causes its meaning to be changed}, for this is what \verb"\noexpand" does to tokens whose meaning is expandable. (Note that \verb"\noexpand" can change the meaning only of the instance of the token to which it applies, and then only for the next execution or expansion). \begin{verbatim} \long\def\isexpandable #1% {% \immediate\write 16 {% The token "\string #1" is \expandafter\ifx\noexpand #1#1% un\fi expandable }% } \end{verbatim} Incidentally, \verb"\relax" is \emph{not expandable}. It does not appear in the list of expandable tokens on [212--215]. Meanings can be divided into two types, expandable and unexpandable. The expandable meaning alter (edit if you will) the input stream of tokens to be processed. They operate in the mouth of \TeX. For example, the commands \verb"\string", \verb"\ifx", \verb"\fi" are expandable, and so function as usual within the \verb"\write" command. The unexpandable tokens work in the stomach, and do something (except \verb"\relax", which is a stomach command that does nothing). They do not operate within mouth contexts, where only expansion takes place. More on this next issue. \noindent {\bf Exercise 3.} Two tokens have the same meaning. When does the substitution of one for the other make a difference? \noindent {\bf Exercise 4.} What operational difference is there between \begin{verbatim} \def\aaa{aaaaaaaa} \def\xyz{aaaaaaaa} \end{verbatim} and \begin{verbatim} \def\aaa{aaaaaaaa} \let\xyz\aaa \end{verbatim} if any at all. [383] would be a good place to start. \end{Article} \endinput