# \DeclareMathOperator: wrong space when the operator is followed by a binary operator

In this answer to the question Shortcuts and/or user-defined shortcuts for math symbols in LaTeX?, it is advised to denote the gradient with \DeclareMathOperator{\grad}{grad}.

But this is suboptimal (wrong space) compared to \mathrm{grad} when the operator is followed by a binary operator (the same with ∇ instead of "grad"), as shown by the following MWE (where only equations ≡ 0 mod 3 are okay):

\documentclass[convert,varwidth=4cm]{standalone}
\usepackage{mathtools}
\usepackage{amssymb}
%
\DeclareMathOperator{\Div}{div}
\DeclareMathOperator{\curl}{curl}
%
\DeclareMathOperator{\nablaop}{\nabla}
%
\begin{document}
\begin{align}
\Div  F & = \grad         \cdot  F \\
\Div  F & = \grad{}       \cdot  F \\
\Div  F & = \mathrm{grad} \cdot  F \\
\curl F & = \grad         \wedge F \\
\curl F & = \grad{}       \wedge F \\
\curl F & = \mathrm{grad} \wedge F \\
\Div  F & = \nablaop      \cdot  F \\
\Div  F & = \nablaop{}    \cdot  F \\
\Div  F & = \nabla        \cdot  F \\
\curl F & = \nablaop      \wedge F \\
\curl F & = \nablaop{}    \wedge F \\
\curl F & = \nabla        \wedge F
\end{align}
\end{document}


Is there a way to make \DeclareMathOperator's behavior okay when the operator is followed by a binary operator?

• you can always make a mathop into a mathord by adding {} as in {\grad} – David Carlisle Jan 28 '16 at 17:00
• Are you willing to accept a syntax such as \grad{f}, \grad{\cdot F} or \grad{\wedge F}? – egreg Jan 28 '16 at 17:40
• @egreg Well... \grad{f} is okay but \grad{\cdot F} and \grad{\wedge F} are conceptually suspect :) – Denis Bitouzé Jan 28 '16 at 19:50
• If you are sure that \grad is always followed by a certain fixed set of tokens, if not by a variable, it can be arranged, I guess. – egreg Jan 28 '16 at 19:58
• @egreg Who knows what mathematicians are able to imagine?! ;) – Denis Bitouzé Jan 28 '16 at 20:00

If you are sure that \grad will be followed by a fixed (but easily extendable) set of binary operators, this should work:

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

% the list of admissible binary operators
\tl_const:Nn \c_denis_grad_ops_tl { \cdot \wedge }

{
}

{
{% if the token matches one in the list, issue {\!}
\token_if_eq_meaning:NNT \l_peek_token ##1 { \tl_map_break:n { {\!} } }
}
}

\ExplSyntaxOff

\begin{document}

\begin{gather*}
\end{gather*}

\end{document}


If a binary operator in the list follows, we issue {\!} that fixes the spacing: the thin space between the operator and the empty atom is nullified by \! and the empty atom will provide the required bit for the spacing around binary operators.

A slightly different version with an interface for adding binary operators; the initial declaration

\OperatorBinary{\cdot,\wedge} % initialize


should go in the class, together with instructions such as

You can define operator names that behave well when followed by binary operation symbols with

\DeclareMathOperatorX{<cs>}{<name>}


for example

\DeclareMathOperatorX{\grad}{grad}


to be used like \grad f or else like \grad\cdot F. The predefined list of admissible binary operators includes \cdot and \wedge, but it can be augmented by saying in the preamble, for instance,

\OperatorBinary{\times}


(the argument can be a list like in the initial declaration which is \OperatorBinary{\cdot,\wedge}. No operator of this type is predefined, use \DeclareMathOperatorX for defining the one you'll be using.

\documentclass{article}
\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\DeclareMathOperatorX}{mm}
{
\NewDocumentCommand{#1}{}
{
\operatorname{#2}
\peek_after:Nw \denis_opx_check:
}
}
\NewDocumentCommand{\OperatorBinary}{m}
{
\clist_gput_right:Nn \g_denis_opx_binary_clist { #1 }
}

\clist_new:N \g_denis_opx_binary_clist
\cs_new_protected:Nn \denis_opx_check:
{
\clist_map_inline:Nn \g_denis_opx_binary_clist
{
\token_if_eq_meaning:NNT \l_peek_token ##1 { \clist_map_break:n { {\!} } }
}
}
\ExplSyntaxOff

\OperatorBinary{\cdot,\wedge} % initialize

\begin{document}

\begin{gather*}

• Interestingly, with\DeclareMathOperatorX{\gradn}{\nabla}, \gradn and \nabla have same output if involved in binary operations (e.g. \gradn \cdot F and \nabla \cdot F) but not if applied to applications (the interspace is bigger e.g. in \gradn F than in \nabla F). Is it a bug or a feature? – Denis Bitouzé Jan 29 '16 at 7:51
• Ooops, sorry for the noise: I should have compared \gradn and \mathop{\nabla}. – Denis Bitouzé Jan 29 '16 at 8:16
\DeclareMathOperator makes a \mathop atom, which are designed for use as prefix functions. In contexts where they are not being used as a prefix application, such as the higher order composition here you can always make a \mathord atom by surrounding with braces, {\grad} which will have the same spacing as \mathrm{grad}