3

A friend shared with me a LaTeX document using essentially the following code, which I was sure wouldn't compile:

\documentclass{amsart}
\begin{document}
\(a_\text b\)
\end{document}

It compiles just fine, with the same result as if more braces were introduced (i.e., \(a_{\text{b}}\)). I was curious what makes this work, and tried:

\documentclass{amsart}
\begin{document}
\(a_\operatorname b\)
\end{document}

This yields the error

! Missing { inserted.
<to be read again> 
                   \let 
l.3     \(a_\operatorname
                         b\)

Inserting braces as \(a_\operatorname{b}\) gives essentially the same error (although, of course, \(a_{\operatorname{b}}\) works). Why do these macros behave differently?

1
  • Presumably because the output ends up being braced/grouped such that what ever ends up being he argument for _ is actually a single group. Thus if the replacement of \text b is similar to (it is not) {\textnormal b} then it works, but if the replacement is \textnormal b (no braces) then it does not work. This is why we always recommend using braces on sub- and superscript (unless it is a single number or symbol and there is no confusing)
    – daleif
    Jan 6 '20 at 16:19
7

First off, \(a_\text b\) is wrong input (it works, yes, but it's wrong nonetheless). The correct input would be \(a_{\text{b}}\), and the same for the \operatorname case. One case works and the other does not due to implementation details of these two macros, which should not be relied upon (they are not likely to change in the near future, but either way. . .)

That said, \text works that way because (after three expansion steps) the first token TeX sees is a {, so it essentially inserts the {. . .} you left out. The first expansion of \text is \protect\text␣␣. Here \protect is \relax (which is ignored here) and \text␣␣ expands to \text@ (after checking that we're in math mode), and \text@ starts with a {.

\operatorname, on the other hand, contains an \@ifstar test, which is not expandable, so the first token TeX sees (after four expansion steps) is \let, which is invalid there, thus it raises an error. You can reproduce the same error by writing \(a_\let\).

9
  • 1
    Upvoted and accepted for the very helpful answer, but with a little reluctance because I think the 'wrong' isn't terribly helpful here. (I'm not sure what it means other than "not best practices", which I think has less of a moralistic connotation, or "subject to implementation details of the macro", which seems to be true for any macro.)
    – LSpice
    Jan 6 '20 at 16:25
  • 3
    @LSpice Yes, you are correct (many things in (La)TeX work (or do not) as they do due to implementation details). With "wrong" I meant that in the LaTeX (and amsmath, since that's an amsmath macro) manuals, you are taught to always use braces for subscripts and for arguments, since otherwise you may fall for implementation detail traps :-) Jan 6 '20 at 16:30
  • 2
    @LSpice Two things are involved here. First is the fact that TeX understands both a_b and a_{b} the same, so you can input either. The second is expandability: your \identity example works because TeX expands it and eventually sees a_b, which is fine. However a_\identity{bc} will not work as a_\text{bc} because it will expand to a_bc, which TeX sees the same as a_{b}c. The braces (rather, catcode-1 tokens) are necessary when grouping multiple tokens in the subscript. And no, character tokens are not expandable (either catcode 11 or 12). Jan 6 '20 at 16:47
  • 1
    @LSpice the thing I think you are missing is that the tex primitive _ and a macro pick up their arguments in completely different ways. An undelimited macro argument #1 is always a single token or an explicit brace group. But a tex primitive _ expands tokens as needed to find the first non-expandable token and then takes an implicit or explicit { token to start a grouped subscript, or the single non brace non expandable token otherwise. Jan 6 '20 at 17:00
  • 1
    @LSpice Implicit as \bgroup in \(a_\bgroup\operatorname b}\) Jan 6 '20 at 17:13
4

enter image description here

Assuming standard catcode regimes so that { starts a group and } end it, then then...

Official LaTex documentation will tell you to always brace the arguments. Partly it does this to avoid having to document what happens if you omit the braces....

A macro scans for an undelimited argument without expanding any tokens, if the next non-space token is a { then the (content of the) group is taken, otherwise the single token is taken as the argument.

Conversely most TeX primitives such as _ or \hbox recursively expand the following token until arriving at a non expandable token and then accepting an implicit or explicit { token to start a grouped argument.

\documentclass{article}

\newcommand \zzA{1234}

\newcommand \zzB{{1234}}

\newcommand \zzC{\zzca}
\newcommand\zzca{\bgroup 1234}



\begin{document}

1 \fbox\zzA  \fbox{\zzA}

2 $X_\zzA   \quad X_{\zzA}$

3 \fbox\zzB  \fbox{\zzB}

4 $X_\zzB  \quad X_{\zzB}$

5 a \fbox\zzC\egroup  b\fbox{\zzC \egroup}

6 $X_\zzC}  \quad X_{\zzC}}$



\end{document}

so note in line 1 the macro \fbox takes all of 1234 as an argument in \fbox\zzA but X_\zzA expands \zzA and so only takes 1 as the subscript.

The behaviour of line 5 is particularly "interesting" we could document a trace through the code and say why no box appears in the unbraced version, but documenting that \fbox (and all latex commands) should always be used with braced arguments is less likely to scare off 99% of the user base.

1
  • For passersby, this was a response to my question in another comment thread. Thanks very much for this thorough workout of the rules and edge cases! As a mathematician, thinking about TeX as I would about math—rather than just as a tool for typesetting math—makes this sort of thing deeply fascinating to me.
    – LSpice
    Jan 6 '20 at 17:47

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.