# Problem of understanding definitions

I have defined a stack structure (I found an example in the LaTeX currfile package, which I adapted to my needs):

\def\MB@modulestack{}
\def\MB@modulestack@push#1{\xdef\MB@modulestack{{#1}\MB@modulestack}}
\def\MB@modulestack@top{\expandafter\MB@modulestack@top@eat\MB@modulestack\relax\relax}
\def\MB@modulestack@top@eat#1#2\relax{#1}
\def\MB@modulestack@pop{\expandafter\MB@modulestack@pop@eat\MB@modulestack\relax\relax}
\def\MB@modulestack@pop@eat#1#2\relax{\gdef\MB@modulestack{#2}}


I understand how it works, especially those \relax. I keep a 4-tuple of parameters there:

\def\MB@modulestack@push{{a}{b}{c}{d}}
\def\MB@modulestack@push{{1}{2}{3}{4}}


Now, to parse such a 4-tuple from the top of stack I wanted to use the following code:

\def\MB@modulestack@topitemparse@eat#1#2#3#4{... here I use #1, #2, #3, #4 ...}
\def\MB@modulestack@topitemparse{
\expandafter\MB@modulestack@topitemparse@eat\MB@modulestack@top
}


...but it didn't work. While experimenting I found that I had to do this another way:

\def\MB@modulestack@topitemparse@eat#1#2#3#4#5\relax{... here I use  #1, #2, #3, #4 ...}
\def\MB@modulestack@topitemparse{
\edef\MB@modulestack@topitem{\MB@modulestack@top}
\expandafter\MB@modulestack@topitemparse@eat\MB@modulestack@topitem\relax\relax
}


Why does the first doesn't work and the second does? Why do I need to get #5 and \relax in the @eat macro? Why do I need to read the top of stack into variable, instead of passing it straight to the @eat macro?

-

This is the classic difference between a macro expansion language and an function-based system. When you do

\def\MB@modulestack@topitemparse{
\expandafter\MB@modulestack@topitemparse@eat\MB@modulestack@top
}


you expand \MB@modulestack@top exactly once, which leaves TeX reading

\MB@modulestack@topitemparse@eat\expandafter\MB@modulestack@top@eat
\MB@modulestack\relax\relax


which does not do what you want. You could work out the exact number of expansions needed to get this to work; in this case, you'd need:

\def\MB@modulestack@topitemparse{
\expandafter\expandafter\expandafter
\expandafter\expandafter\expandafter
\expandafter\MB@modulestack@topitemparse@eat\MB@modulestack@top
}


which will expand everything as you want. However, this is clearly awkward, which is where \edef comes in as it always fully-expands stuff. The only danger is that the result of

\edef\MB@modulestack@topitem{\MB@modulestack@top}


might not be what you expect if the stack items are themselves expandable.

-
So \expandafter does only single level of expansion, not a full expansion I expected--like LISP's macroexpand-1, and not macroexpand. Thanks, that makes one thing clear. –  liori Apr 1 '11 at 15:44
@liori: No idea, I don't use LISP. The general point is that when you read carefully-written programming guides for TeX, each macro is always described as inserting <replacement text>, which is what happens at each expansion. So \expandafter does one expansion, replacing a macro by it's <replacement text>. –  Joseph Wright Apr 1 '11 at 15:50
@liori: I'm sure Lispers are crying their hearts out with the use of word macro in TeX. Macro in Lisp is a wholly different beast from the word "macro" in pretty much any other context. –  morbusg Apr 1 '11 at 16:44

Joseph already explained why and how it works. Here an alternative way to do this without using \expandafter to much:

Instead of using the @top macro as part of an argument, you can define it to "call" the parse macro with the top of the stack:

\def\MB@modulestack@top{\expandafter\MB@modulestack@top@call\MB@modulestack\relax}
\def\MB@modulestack@top@call#1#2\relax#3{#3#1}% here #1 are the four {.}{.}{.}{.} pushed on the stack


The parse macro simple receives the four arguments:

\def\MB@modulestack@topitemparse#1#2#3#4{%
% do what you want with the four arguments
}


Usage:

\MB@modulestack@top\MB@modulestack@topitempars


The \MB@modulestack@topitempars could also be hardcoded into \MB@modulestack@top@call.

-