[Tex/LaTex] way to define a newcommand that can evaluate mathematical expressions

macros

Let's suppose that I have a very complicated function that depends on i and j.
So I define a new command, say

\newcommand{\foo}[2]{X_{i+j+1}}. % This might be an complicated expression, but I want to keep it simple

Using this definition, I can invoke this command like \foo{\alpha}{\beta} or \foo{2}{3}.
Now, what I want to get is if both of arguments are numerical values, I want to force them to evalue this expression, i.e., \foo{2}{3} should generate X_{6} instead of X_{2+3+1}. It is sometimes annoying that I should manually simplify it even though I know the full expression.

I actually feel this seems almost impossible but I anyway would like to ask in case there exists some workarounds.

Best Answer

This seems to be a job for l3regex:

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

\ExplSyntaxOn
\NewDocumentCommand{\evaluateorprint}{m}
 {
  \regex_match:nnTF { [^0-9+\-] } { #1 }
   { #1 }                 % symbolic expression
   { \int_eval:n { #1 } } % only numbers, + or -
 }
\ExplSyntaxOff

\newcommand\foo[2]{%
  X_{\evaluateorprint{#1+#2+1}}%
}

\begin{document}
\[
\foo{2}{3}+\foo{\alpha}{\beta}
\]
\end{document}

enter image description here

A version without l3regex that might be more likely accepted by publishers relying on older TeX distributions (courtesy of Bruno Le Floch):

\ExplSyntaxOn
\NewDocumentCommand{\evaluateorprint}{m}
 {
  \group_begin:
  \cs_set_eq:NN \__sungmin_eval:n \int_eval:n
  \tl_map_inline:nn { #1 }
   {
    \tl_if_in:nnF { 0123456789+-*() } { ##1 }
     {
      \cs_set_eq:NN \__sungmin_eval:n \use:n
     }
   }
  \__sungmin_eval:n { #1 }
  \group_end:
 }
\ExplSyntaxOff

The function \__sungmin_eval:n is tentatively set equal to \int_eval:n; then the argument is scanned token by token; if something not legal in a numeric expression is found, \__sungmin_eval:n is changed into \use:n that simply outputs the argument without any processing.

Related Question