10

Sometimes I define model commands (\foo in the example below) and then particular commands based on that model (\fool in the example below). However, I am not entirely sure I am using the correct syntax.

\documentclass{minimal}
\usepackage{xparse}
\NewDocumentCommand\foo{mm}{#2#1}
\NewDocumentCommand\fool{}{\foo!}
\NewDocumentCommand\foot{m}{\foo!{#1}}

\begin{document}
   \fool{⟨sth⟩}, \foot{⟨sth⟩}
\end{document}

Do \fool and \foot behave differently? Is one better than the other? As I understand it, both \fool{⟨sth⟩} and \foot{⟨sth⟩} expand to \foo!{⟨sth⟩} and then to ⟨sth⟩!, which is the expected result. Is it correct?

  • 1
    Welcome to TeX.SE. Basically, you're applying the moving arguments technique. This is often used in the TeX/LaTeX core and package code, but is it really needed with \NewDocumentCommand? Using \meaning\foot and \meaning\fool shows that the code behind them is not the same – user31729 May 13 '17 at 16:21
9

TeX is a macro expansion language. If we look at some random definitions in plain.tex, we find some that only appear to have an argument. For instance

\def\line{\hbox to\hsize}

that should be called \line{text}. So, what appears to be the argument to \line is actually the argument to \hbox to\hsize.

The LaTeX model is more complicated. For instance, \makebox is

\DeclareRobustCommand\makebox{%
  \leavevmode
  \@ifnextchar(%)
    \@makepicbox
    {\@ifnextchar[\@makebox\mbox}}%

which has no argument. Grabbing the argument is deferred to \@makepicbox, \@makebox or \mbox, depending on the token that follows.

The same approach is used by xparse. If you look at the definition of \foo after your definition, you'll see

> \foo=\protected macro:
->\__xparse_start_expandable:nNNNNn {mm}\foo  \foo  \foo code ?{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w }.

so \foo has no argument (like \makebox). The arguments are actually grabbed by \foo•code (the bullet means a space in the name) in a quite complex way, because the aim is to be able to specify complex sequences of mandatory or optional arguments. Here is its definition:

> \foo code=\protected\long macro:
#1#2->#2#1.

On the other hand, if you did

\NewDocumentCommand{\foo}{O{x}m}

then the definition of \foo would be

> \foo=\protected macro:
->\__xparse_start:nNNnnn {O{x}m}\foo  \foo code {\__xparse_grab_D:w []\__xparse_grab_m_1:w }{{\prg_do_nothing: x}\c__xparse_no_value_tl }{}.

but \foo•code would be the same as before.

Similarly for \fool and \foot. Both version would work the same, eventually, because both will end up in

\foo•code ! {(sth)}

in the main input stream.

The only difference is that the second argument would be read twice with \foot and only once with \fool. A saving in time that's not worth the pain, in general.

A recommendation when using \NewDocumentCommand and friends is to always specify the full set of arguments. There are however cases where using the “reduced” version is easier, but they should be kept to a minimum for maximum readability of the code.

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.