# Align*, & and \futurelet

can somebody explain futurelet within align-environments?

## Example:

The command \A should give an "A" if the next char is a {, a "B" if it is & and "C" in any other case.

\gdef\A{\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}


and in case of normal text or inline math, it works quite fine:

\A{a},\A&,\A a       % -> "A,B,C"
$\A{a}$,$\A&$,$\A a$ % -> "A,B,C"


but the moment I use it within an align*-environment (amsmath) there is an "Incomplete \ifx"-error:

\begin{align*} \A{a},\A&,\A a \end{align*}% --> error.


Can somebody explain it to me? Thx!

Chris

PS: There are more things about futurelet in an align environment which I do not understand: If we define

\gdef\A{\futurelet\thesymbol\alpha}
\gdef\D#1{\detokenize{#1}}


then

\begin{align*}
\D&,\A a    % -> "&,alpha a" (okay)
\A a,\D{&}  % -> "alpha a,&" (okay)
\A a,\D&    % -> error: "Argument of D has an extra }." (???)
\end{align*}

-
I've been using TeX and friends for 20 years and I still don't get \futurelet. –  Matthew Leingang Apr 8 '13 at 19:09
Wrap the entire thing inside a group {...} inside the align* environment to hide & from being interpreted/used by align. –  Werner Apr 8 '13 at 19:11
Okay... That would work. Is it possible without an extra group? I have to (not want to) write a command which (under some circumstances) will parse additionally parameters, add newlines (\) and alignments (&), so a surrounding group is problematic (first example in tex.stackexchange.com/questions/104398/…)) –  Elgrimm Apr 8 '13 at 19:22
@Elgrimm: to make it work without an extra group, try putting \catcode&=12 before the \futurelet in \A and then \catcode&=4 at the end of \B. This prevents TeX from reading the & as a tab character during the processing of your macro. Beware! This has numerous pitfalls and is also untested. –  Ryan Reich Apr 9 '13 at 0:33

\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi}


when TeX sees the & it swaps in the rest of the template for the \halign as specified in latex case by c r etc, so the \ifx will compare the first two tokens of the template (probably \unskip and \hfil then the cell (and so the group) will end things go wrong.

If you want to hide & while starting a group in before the futurelet and ending it after the test you need the

{\ifnum0=}
...
\ifnum0={\fi}


form that appears all over any tabular code.

This produces A,B,C which is I think the intended result.

\documentclass{article}
\usepackage{amsmath}

\gdef\A{{\ifnum0=}\fi\futurelet\thesymbol\B}
\gdef\B#1{\ifx\bgroup\thesymbol A\else\ifx&\thesymbol B\else C\fi\fi \ifnum0={\fi}}

\begin{document}

\begin{align*} \A{a},\A&,\A a \end{align*}

\end{document}


For your second example note that & ends a group so

a,\D& is like {\D} and both give the same error:

! Argument of \D has an extra }.
<inserted text>
\par
l.15 {\D}


There it isn't so clear what the fix is as it is not clear what you want {\D} to do.

-
This is precisely why I'm against downvoting questions. I can ask a papazillion questions about this answer alone and all would be ridiculously localized. In other words it won't help anyone else. –  percusse Apr 8 '13 at 20:22

I can't compete with David's understanding of TeX code, so I won't try to fix your macros (my opinion is that what you are doing is fundamentally unwise, though). However, his comment about "when TeX sees the &" can be expanded as follows. In scanning an alignment, TeX acts in a manner that is somewhat at odds with the mental model most users (even experienced and knowledgeable users) have of its execution. Namely, we imagine that TeX is always doing one of three things:

1. Scanning the input so as to tokenize the characters to provide food for the macro parser "mouth";

2. Expanding macros;

3. Executing non-expandable tokens: either programming directives like \def or \hbox, or outright typesetting commands such as characters.

Under this model everyone expects that inside an alignment (the TeX primitives \halign or \valign) the tab character & takes its action under point 3: execution. This is not really the case, however; in fact, TeX "notices" tab characters in point 1! If TeX ever reads an ampersand (or equivalent category of character) it will immediately end the current cell, closing a group, inserting the "v part" of the template, and so on.

(Edit: I was just skimming errorlog.pdf (that is, texdoc errorlog) and found the relevant comment from a debugging session on 18 March 1978:

Make the get next routine intercept & and \cr tokens. I’d thought I could just put & and \cr into big_switch [i.e., in the stomach of TeX, not the eyes]; that was a great big mistake.

This is an interesting partial insight into what led Knuth to make the above, apparently bizarre, choice of behavior of these array tokens, as well as confirmation that this really is the behavior.)

The exception, of course, is when TeX is inside an unfinished brace group (and it must be actual brace characters, not implicit ones or \begingroup, that start this group), which leads to David's {\ifnum0=} construction that is expandably equivalent to an open brace without actually creating unbalanced braces inside a macro definition where it might be placed.

The result of this weird parsing rule is that one has to be very careful with what gets read by a macro in a table cell, or enclosed by an environment. Macros such as yours, which effectively read their argument through assignment rather than macro-argument parsing, are even more precarious, since without the requisite enclosing braces, the tab that could be read would not be protected. Table-compatible environments include the \ifnum` thing so as to protect any tab characters that might occur within; more naive ones will be split across cells and, thus, probably fail.

-