# Alternative for \DeclareMathOperator

I'm getting a little tired of defining all my mathematical operators with \DeclareMathOperator. Also it is rarely useful to have them as a macro. On the contrary it sometimes leads to macro name collision (e.g. \span). So I came up with the following:

\documentclass{article}
\usepackage{amsmath}
\catcode\¡=\active
\def¡#1!{\operatorname{#1}}
\begin{document}
$e^{ix} = ¡cos! x + i¡sin! x$
\end{document}


I'd like to get rid of the ! at the end and maybe use \ifmmode, to allow ¡ in normal text. Is that possible? Are there other side effects of my definition I should be aware of?

-
\newcommand{\op}[1]{\operatorname{#1}}. However, I can't understand the point. –  egreg Feb 8 '14 at 18:11
@egreg: Then I would have to write braces around the name. I don't want to write more than if I had used \DeclareMathOperator. –  canaaerus Feb 8 '14 at 18:12
How can TeX know where to end the operator name? –  egreg Feb 8 '14 at 18:13
It does know it for all the usual commands that start with \ . –  canaaerus Feb 8 '14 at 18:14
You're starting from a false premise. It's good to have a macro for constructs that are frequently used, such as the name of functions. –  egreg Feb 8 '14 at 18:27

You are starting from a false premise: it's good to have macros for frequently used constructs and math operators such as “sine” and “log” are no exception.

If an operator appears only a few times, then what's wrong in using

\operatorname{foo}


for those few cases? If you don't want to type so much, then

\newcommand{\op}[1]{\operatorname{#1}}


would allow simply typing

\op{foo}


that requires just three keystrokes more than your proposed syntax.

It's quite difficult to have a safe routine for scanning a name in the same way TeX does for control sequences. The scanning of control sequence names is built-in, while you should do it character by character, storing them as you go until finding something that's not a letter.

There's another catch: your proposed character ¡ will definitely not work if the document is compiled under

\usepackage[utf8]{inputenc}


because in that case it is not a single character, but two: its UTF-8 representation is 0xC2A1. You could use , instead.

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

\ExplSyntaxOn
\tl_new:N \l__canaaerus_name_tl

\cs_new_protected:Npn \canaaerus_bq_mathop:
{
% clear the container
\tl_clear:N \l__canaaerus_name_tl
% start the recursion
\canaaerus_absorb:
}

\cs_new_protected:Npn \canaaerus_absorb:
{
\peek_catcode:NTF a
{% if the next token is a letter absorb it
\__canaaerus_absorb_next:n
}
{% otherwise produce the operator name
\__canaaerus_deliver:
}
}

\cs_new_protected:Npn \__canaaerus_absorb_next:n #1
{
% add the next letter to the container
\tl_put_right:Nn \l__canaaerus_name_tl { #1 }
% restart the recursion
\canaaerus_absorb:
}

\cs_new_protected:Npn \__canaaerus_deliver:
{
% produce the operator name
\operatorname{\l__canaaerus_name_tl}
}

% define the active back quote
\group_begin:
\char_set_catcode_active:N 
\cs_gset_eq:NN  \canaaerus_bq_mathop:
\group_end:
\ExplSyntaxOff

% make the backquote math active
\AtBeginDocument{\mathcode=\string"8000 }

\begin{document}

$cos(\alpha+\beta)-sin x$

\end{document}


Highly inefficient, but working. Of course, syntax errors such as typing

sinx


wouldn't be caught.

A different approach is to ease defining operators:

\documentclass{article}
\usepackage{xparse,amsmath}
\ExplSyntaxOn
\NewDocumentCommand{\DeclareMathOperators}{m}
{
\keys_set:nn { canaaerus/mathop } { #1 }
}

\keys_define:nn { canaaerus/mathop }
{
unknown .code:n = \canaaerus_defop:n { #1 }
}

\cs_new_protected:Npn \canaaerus_defop:n #1
{
\cs_if_exist:cTF { \l_keys_key_tl }
{
\msg_error:nnx { canaaerus/mathop } { exist } { \exp_not:c { \l_keys_key_tl } }
}
{
\tl_if_empty:nTF { #1 }
{
\cs_new:cpx { \l_keys_key_tl } { \exp_not:N \operatorname { \l_keys_key_tl } }
}
{
\cs_new:cpx { \l_keys_key_tl } { \exp_not:N \operatorname { #1 } }
}
}
}
\msg_new:nnnn { canaaerus/mathop } { exist }
{
}
{
}
\cs_generate_variant:Nn \msg_error:nnn { nnx }
\ExplSyntaxOff

\DeclareMathOperators{
Tor,
Hom,
Span=span,
%span, % if uncommented it would raise an error
}

\begin{document}
$\Tor\quad\Hom\quad\Span$
\end{document}

-
Can I use your code for defining a \DeclareMathOperators command as is, in a personal .sty or .cla file. I as k this question because it begins with \NewDocumentCommand – and a .sty or .cls file isn't really compiled. –  Bernard Feb 8 '14 at 23:59
@Bernard You can put the code in a .sty file; just change \usepackage into \RequirePackage. Put there all from \RequirePackage to \ExplSyntaxOff –  egreg Feb 9 '14 at 0:19
Is it possible to get the character used (backtick or ¡) from a macro (e.g. an argument to a package)? I tried to place \expandafters but it wouldn’t work... –  canaaerus Feb 9 '14 at 14:29
@canaaerus \expandafter` is not abracadabra; what precisely do you want to do? –  egreg Feb 9 '14 at 16:56
@cfr Yes, XeLaTeX and LuaLaTeX first transform UTF-8 multibyte combinations into single characters. –  egreg Feb 9 '14 at 20:24