# Where is the argument?

I have this code on my hard disk and now I would like to understand it. Firstly I would like to know if this code is correct and logic or if there is another way to do the same thing.

\documentclass{article}
\usepackage{fp}

\newcommand*\macro[2][]{%
Option : #1\par % print the option in #1
\let\y #2 % to keep
\begingroup
\catcode$$=1 \catcode$$=2
\macrobis
}
\newcommand*\macrobis[1]{%
\endgroup
\scantokens{\def\temp{#1}}}

\begin{document}

\def\fct{x*x}

\macro[op]{\fct}(exp(1))

\FPeval\x{\temp}%
\FPeval\img{\y}%
x = \x\ donne  y = \img

\end{document}


\begingroup and \endgroup are here, I suppose, because the code changes the catcodes but tha call of macrobis is very strange. Where is the argument ? Can someone explain this code?

-

Let's see one command at a time:

\newcommand*\macro[2][]{%
Option : #1\par % print the option in #1
\let\y #2 % to keep
\begingroup
\catcode$$=1 \catcode$$=2
\macrobis
}


\macro has one optional argument (default empty) and a mandatory one. It assumes that the mandatory argument is one token, as it does \let\y#2 (but will leave a space in the input stream). Then it opens a group where it sets ( and ) as delimiters just like { and }; after this it calls \macrobis.

\newcommand*\macrobis[1]{%
\endgroup
\scantokens{\def\temp{#1}}}


\macrobis gathers its argument considering ( and ) as braces. Then it ends the group, so ( and ) return to their previous status and defines \temp to expand to #1 but inside \scantokens so the possible ( and ) characters in #1 will be rescanned in this setting where they are not delimiters any more.

What appears to be a parenthesized second mandatory argument to \macro is actually the argument to \macrobis, but this is not relevant from a user's point of view.

The point is to hide possible parentheses in that argument: if one defined

\newcommand*\macro[2][]{%
Option : #1\par % print the option in #1
\let\y #2 % to keep
\macrobis}
\def\macrobis(#1){\def\temp{#1}}


then an input such as \macro[op]{\fct}(exp(1)) would interpret exp(1 as the argument to \macrobis, which would be wrong.

-
This is magic ! –  Alain Matthes Dec 29 '11 at 17:31
@Altermundus A slick trick indeed! –  egreg Dec 29 '11 at 17:32
There is no problem with the first (but why it's the last ) that is used like a brace ? –  Alain Matthes Dec 29 '11 at 17:54
@Altermundus In order to gather the argument! In the example, when \macrobis is called, this is equivalent to write {exp{1}} so everything is balanced and the argument is exp(1) (TeX considers those as delimiters, but after \scantokens they return to be as normal). –  egreg Dec 29 '11 at 17:58

As far as I interpret it, macros (or control sequences) could be considered "replacements" for larger constructs (here "larger constructs" refers to the macro contents). As such, \macro gobbles \macro[op]{\fct} since it requires 2 arguments, does some magic, and replaces it with \macrobis. Still left in the input steam is (exp(1)) with the category codes changed for ( and ) to group beginning and endings, respectively. So, effectively you're left with \macrobis{exp(1)}, which represents valid input for \macrobis, since it requires a single argument.

On a related note, consider the following. \FPeval is a macro that takes two arguments as is evident from \show\FPeval:

> \FPeval=macro:
#1#2->\FP@eval {#1}{#2}.


However, if you define

\newcommand{\myfunc}{\FPeval}


where \myfunc now takes no arguments, and use

\myfunc\x{\temp}%
\myfunc\img{\y}%
x = \x\ donne  y = \img


you'll get the same output, illustrating the idea behind replacement.

-
Good remark with \newcommand{\myfunc}{\FPeval} –  Alain Matthes Dec 29 '11 at 17:48