7

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
3
  • @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, 2017 at 16:28
  • I see, yes I probably don't understand everything here. Aug 23, 2017 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). Aug 23, 2017 at 17:01

1 Answer 1

13

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.

3
  • Thanks! What is cur_chr normally, for tokens that are not flagged as temporarily non-expandable?
    – Evan Aad
    Aug 24, 2017 at 9:23
  • 1
    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, 2017 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, 2017 at 9:43

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.