# How to make latex parse x as an argument of a macro definition instead of #1

When I define a mathematical function for plotting in pgfplots or pstricks I usually to it in the following way:

\def\f(#1){(#1)^3 + 3*exp(#1)}


just as suggested by Jake in his answer to a question about how to define a function consistently for plotting and computations in pgfplots with and without gnuplot.

However is it possible to define say \defF such I can write:

\defF\f(x){x^3 + 3*exp(x)}


which should be equivalent to the first definition using \def and #1 above?

Long answer: yes, it can be done.

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

\ExplSyntaxOn
\NewDocumentCommand{\functiondef}{mr()m}
{% #1 = function name (a macro), #2 = variable, #3 = formula
\tl_set:Nn \l_tmpa_tl { #3 }
\regex_replace_all:nnN { \b#2\b } { \cP\#1 } \l_tmpa_tl
\cs_gset:cV { function_inner_\cs_to_str:N #1 :n } \l_tmpa_tl
\cs_new:Npn #1 ( ##1 )
{
\use:c { function_inner_\cs_to_str:N #1 :n } { ##1 }
}
}
\cs_generate_variant:Nn \cs_gset:Nn { cV }

\cs_set_eq:NN \eval \fp_eval:n
\ExplSyntaxOff

\functiondef\f(x){x^3 + 3*exp(x)}

\begin{document}

\eval{\f(42)}

\end{document}


Here I use \fp_eval:n, adapt it to PGF.

If I do

echo '42^3+3*e(42)' | bc -l


I get

5217824824561577230.18404391083370567842


The accuracy depends, of course, on the number crunching engine.

## Explanation

The replacement text is stored in a sequence; every appearance of x (the stated variable name, more generally) surrounded by word boundaries is replaced by #1. This token list is then passed to \cs_gset:cV that builds a regular macro named \function_inner_f:n (the actual name is built from the first argument to \functiondef) and then the macro \f with the argument surrounded by parentheses is defined to use \function_inner_f:n.

• Great, thanks a lot. And yes I think that the code gains readability. In some cases I can also use directly copy and paste without doing a (admittedly simple) search and replace step (x -> #1). Jan 1 '15 at 11:26
\documentclass{article}
\usepackage{pst-func}
\def\f(x){x^3 + 3*Euler^x}
\begin{document}

\psPrintValue[algebraic,valuewidth=20]{42,\f(x)}

\end{document}