Trying to understand the definition of \newcommand (complex handling of parameter tokens)

Your reasoning is correct except for what the #{ parameter does.

When TeX sees a # in the <parameter text> of a macro (as in \def\macro<parameter text>{<replacement text>}), the following token can be either a digit in the range 1–9, or a {. When the parameter is "the dreaded weird #{ parameter", then TeX behaves as if the delimiter of the previous argument was a { (since you can't use a { in the <parameter text>).

In this definition (remember the {\bar} is still in the input stream):

\def\reserved@a #12#2#{%
\expandafter\def\expandafter\foo\reserved@b #12%
}%
\l@ngrel@x \reserved@a 0#1#2#3#4#5#6#7#8#9#2{\bar }

when \reserved@a expands, #1 will be, as you said, 0#1#, and #2 will be everything up to the next {, and not empty, so #3#4#5#6#7#8#9#2, delimited by the { in {\bar }. This definition of \reserved@a effectively throws away the remaining parameter tokens. So your "pretend[ing] that string before the {\bar} isn't there" was actually correct. The rest of the code executes as you assumed.


A quote from The TeXbook, about the #{ parameter:

A special extension is allowed to these rules: If the very last character of the <parameter text> is #, so that this # is immediately followed by {, TeX will behave as if the { had been inserted at the right end of both the parameter text and the replacement text. For example, if you say '\def\a#1#{\hbox to #1}', the subsequent text '\a3pt{x}' will expand to '\hbox to 3pt{x}', because the argument of \a is delimited by a left brace.


I've already dealt with the problem in my book on LaTeX programming. My example is slightly different, but it's easier to copy. ;-) Suppose we have

\newcommand{\xyz}[2]{ab#1cd#2ef}

This becomes

\@star@or@long\new@command[2]{ab#1cd#2ef}

As there is no * after \new@command, this does \let\l@ngrel@x=\long and \@star@or@long disappears. Now \new@command is expanded, yielding

\@testopt{\@newcommand\xyz}0[2]{ab#1cd#2ef}

This becomes

\kernel@ifnextchar[{\@newcommand\xyz}{\@newcommand\xyz[{0}]}[2]{ab#1cd#2ef}

The purpose is to add [0] if the number of arguments is not given. Since there is a [, we get

\@newcommand\xyz[2]{ab#1cd#2ef}

Now comes the lookup for a further optional argument, which I skip, and we obtain

\@argdef\xyz[2]{ab#1cd#2ef}

The token \xyz is checked for definability; if it is not definable we get the error message, otherwise

\@yargdef\xyz\@ne{2}{ab#1cd#2ef}

and this is where the real fun starts:

\ifx\@ne\tw@
  \def\reserved@b#11{[##1]}
\else
  \let\reserved@b\@gobble
\fi
\expandafter\@yargd@f\expandafter{\number2}\xyz{ab#1cd#2ef}

This defines \reserved@b to be \@gobble and leads to

\@yargd@f{2}\xyz{ab#1cd#2ef}

Recall the definition of \@yarg@def:

\long\def\@yargd@f#1#2{%
  \def\reserved@a##1#1##2##{%
    \expandafter\def\expandafter#2\reserved@b##1#1}%
  \l@ngrel@x\reserved@a0##1##2##3##4##5##6##7##8##9###1%
}

The arguments are #1=2 and #2=\xyz, so we get (double ## are here reduced to a single #)

\def\reserved@a#12#2#{\expandafter\def\expandafter\xyz\reserved@b#12}
\l@ngrel@x\reserved@a0#1#2#3#4#5#6#7#8#9##1{ab#1cd#2ef}

The first argument to \reserved@a is delimited by 2, the second argument by {. This is a particular feature of TeX: the final argument can be delimited by the opening brace of the replacement text.

Thus the first argument is, in our case, 0#1#. Since \l@ngrel@x is \long it triggers the expansion of \reserved@a with the stated arguments:

\long\expandafter\def\expandafter\xyz\reserved@b0#1#2{ab#1cd#2ef}

Since \reserved@b is \@gobble, we end up with

\long\def\xyz{ab#1cd#2ef}