5

The TeXbook (20th printing, Addison-Wesley 1991) describes how the primitive \noexpand<token> is expanded (p. 213):

The expansion is the token itself; but that token is interpreted as if its meaning were ‘\relax’ if it is a control sequence that would ordinarily be expanded by TeX’s expansion rules.

In light of this I expect the following plain TeX manuscript to typeset "yes". In fact, it typesets "no". Why?

\def\foo{bar}%
\expandafter\ifx\noexpand\foo\relax yes\else no\fi%
\bye
  • @ShreevatsaR: Going by your logic, \expandafter\meaning\noexpand\foo is just like \meaning\foo and should therefore typeset "macro:->bar", but in fact it typesets "\relax". – Evan Aad Aug 23 '17 at 16:28
  • I see, yes I probably don't understand everything here. – ShreevatsaR Aug 23 '17 at 16:29
  • 1
    I suppose you could argue that \foo in this context is not a control sequence that would ordinarily be expanded by TeX’s expansion rules. For \ifx does not expand; it only checks whether two tokens mean the same. Unfortunately, this “explanation” does not explain the difference between \ifx and \meaning: The latter does not expand its argument either. I suppose it boils down to reading the TeX source code (which I never tried). – Harald Hanche-Olsen Aug 23 '17 at 17:01
11

You have to look first at module 358 of tex.web, where no_expand_flag is defined to be 257 (the comment says this characterizes a special variant of relax). When a macro is preceded by \noexpand, the variable cur_chr is assigned no_expand_flag and cur_cmd is assigned relax.

enter image description here

Module 507 explains how \ifx works: first the next token is stored, along with its cur_cmd and cur_chr values in p and q; thereafter, another token is absorbed and its cur_cmd is compared with p. In your case, this test returns true, because both values are relax.

However, now b (the return value of the conditional) is returned the truth value of cur_chr = q and these don't match.

enter image description here

The conclusion is that the expansion of \noexpand\foo is \relax, but not as far as \ifx is concerned and that this is by design.

  • Thanks! What is cur_chr normally, for tokens that are not flagged as temporarily non-expandable? – Evan Aad Aug 24 '17 at 9:23
  • By the way, I disagree with your statement that "the conclusion is that ... this is by design". By definition you cannot tell whether a certain implementation is by design by merely reading the code; the design must be clearly specified in a meta-language, e.g. in comments or in the documentation. Otherwise, every bug would be "by design". – Evan Aad Aug 24 '17 at 9:30
  • 2
    @EvanAad “this characterizes a special variant of relax” seems to me clear enough a statement that this relax is not the same as one the user can input as \relax. The values assigned to cur_chr are clearly explained in tex.web. – egreg Aug 24 '17 at 9:43

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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