7

Reading physics.sty available on CTAN as physics package I found the line

\DeclareDocumentCommand\quantity{}{{\ifnum\z@=`}\fi\@quantity}

which I don't understand. I is clear that \quantity is defined as a call to \@quantity. But what the construct

{\ifnum\z@=`}\fi

do?

8
  • It's a trick to have an unbalanced brace. This answer explains a similar case. – campa Aug 16 '17 at 6:37
  • It's for when you have something looking ahead for a literal brace and \bgroup wouldn't do. – Henri Menke Aug 16 '17 at 6:42
  • If you look at the definition of \@quantity you'll see that it ends with \ifnum\z@=`{\fi}, which provides the closing brace. – campa Aug 16 '17 at 6:43
  • I still wonder. \z@ is just zero, and ``}` is octal code of the closing brace, right? So, {\ifnum\z@=}\fi` is always evaluated to false and skipped. What is then the difference of \DeclareDocumentCommand\quantity{}{{\ifnum\z@=}\fi\@quantity}` from \let\quantity\@quantity? – Igor Kotelnikov Aug 16 '17 at 10:56
  • 2
    See The TeXbook, Appendix D, section 5 (Brace Hacks). – GuM Aug 16 '17 at 11:06
4

The coder wanted the \quantity macro to expand to {\fi\@quantity. However, this does not work in a macro definition as the { is not closed and the TeX compiler would look for the closing } further on. To still get this done a trick is used to add a } which is taken as a closing group during macro definition but is ignored (i.e. removed) during macro execution.

This is done by adding \ifnum\z@=`}\fi so the macro definition has now matching braces so the compiler is happy here. Then during macro execution the ` actually turns the } into a number (its ASCII number AFAIK). This number is compared with \z@ (=0) using \ifnum\z@= just to remove it again without producing any output. As the closing \fi is following directly thereafter the whole thing \ifnum\z@=`}\fi expands to nothing independent on the actually number value.

For this to work there should be a matching \ifnum 0=`{\fi} following in a macro which is called later on in the process.

One other place this is used is in \hline. See the explanation there.

1
  • 1
    The coder wanted that but he's wrong in wanting it to begin with. ;-) – egreg Nov 29 '17 at 22:53
4

Just follow the expansions. If TeX finds the call

\quantity\big(x)

it will do

{\ifnum\z@=`}\fi\@quantity\big(x)

Now TeX expands tokens or pushes them through the gullet. In this case { is pushed down (and a simple group is opened) and \ifnum is expanded. Since the test is false, only \fi remains (actually it's irrelevant that the test is false). The expansion of \fi is empty and TeX proceeds to expand \@quantity.

This is more complicated and the subsequent processing involves some \let, which are the reason for doing everything in a group. The end result is

\bigl(x\bigr)\ifnum\z@=`{\fi}

After expansions and executions, the math list corresponding to \bigl(x\bigr) is built and finally \ifnum is expanded, leaving again nothing behind it; the trailing } closes the group started at the beginning.

If we look at what we got, that macro call is essentially the same as doing

{\bigl(x\bigr)}

which is wrong. For instance,

\log\quantity\big(x)

would result in a thin space between the operator and the parentheses, because

\log{\bigl(x)\bigr)}

treats the subformula in braces as a unique ordinary symbol. Here's the visual proof:

\documentclass{article}
\usepackage{physics}

\begin{document}

$\log\quantity\big(x)$

$\log\bigl(x\bigr)$

\end{document}

enter image description here

This wouldn't happen if the definition is

\DeclareDocumentCommand\quantity{ t\big t\Big t\bigg t\Bigg g o d() d|| }
{\begingroup
 % Flexible automatic bracketing of an expression in () or [] or {} or ||
        % Handles manual override of sizing
 [...many lines of code...]
        {\ltag\lbrace#5\rtag\rbrace  \IfNoValueTF{#6}{}{[#6]} \IfNoValueTF{#7}{}{(#7)} \IfNoValueTF{#8}{}{|#8|}}
        \endgroup
}

I see no reason for a separate macro \@quantity. Using a semisimple group avoids the problem with a subformula:

\log\begingroup\bigl(x\bigr)\endgroup

does not consider the tokens in the group to make a subformula and the spacing between the Op atom \log and the Open atom \bigl( would be the right one.

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.