I want to define a command \NewSmartOp such that:
\NewSmartOp \MYOP \myop
would produce the following code (or anything equivalent):
\makeatletter
\def\MYOP{\@ifstar\MYOP@star\MYOP@nostar}
\def\MYOP@star#1{\myop\!\left( #1 \right)}
\def\MYOP@nostar#1{\myop #1}
\makeatother
I guess I need \expandafter and perhaps \csname … \endcsname but otherwise I have no clue how to generate these definitions, especially regarding how to form a new command name \MYOP@star from \MYOP, and also how to deal with these #1 that must be kept as-is in the produced definitions (by contrast with being expanded by the definition producing them).
Background (reading optional)
For a bit of context: when typing math I want to abstract from concrete syntax as much as possible. For instance, for cardinality of set S, perhaps I’d like it to be rendered as card S (with parentheses only when needed, e.g. card(S₁ ∪ S₂)), but perhaps at some point in the future I’d like to switch syntax to |S|. So I would define:
\DeclareMathOperator \card {card}
\NewSmartOp \CARD \card % option 1
%\newcommand* \CARD[1] {\left\lvert # \right\rvert} % option 2
after which
- I might use the operator directly (low-level, my TeX typing reflects the concrete syntax):
\card Sor\card(S); - but I’d rather use a command with an argument to which I defer the concrete syntax (high-level, my TeX typing reflects the abstract syntax tree):
\CARD {S}.
This ideal seems hard to achieve fully because I cannot(?) find out automatically when parentheses are needed, so the compromise I adopted is to have stared versions of these “smart operators” add parentheses: \CARD* {S_1 \cup S_2}.


\expandafter! “why not defining\CARDdirectly” → If you mean without\@CARDand such, then I simply applied the recipe I found there for star-able commands; if you mean without a\NewSmartOphelper, then it’s because it’s a boilerplate pattern I will repeat many times (… i.e. the usual case for macros). You taught me about\operatorname, though. :-) – Maëlan May 11 '22 at 22:28\leftand\rightindiscriminately around delimiters. In some cases they're useful, in most cases they produce oversized parentheses. Try\left(\hat{b}\right), for instance. If you want parentheses, use them explicitly in the input (or use something likemathtoolsoffers with\DeclarePairedDelimiter). – egreg May 11 '22 at 22:37\leftand\right, but it was just too much having to care for that additional bit. Defining yet another version of all commands that put parentheses… Still it was not the question, but I leave your answer as the solution anyway, since it taught me how to solve my problem. – Maëlan May 11 '22 at 22:41semantex(see other answer). I just note that you may simplify the definition a bit by letting\parentheseseat the star (only, it won’t be eaten if not preceded by a plus). – Maëlan May 12 '22 at 09:26