The main difference is that using \afterassignment
you can preserve the assignment syntax.
So in your counter example any number of tokens following \dosomething
would be expanded until a sequence of non expandable tokens making a <number>
are scanned. The second version forces a macro-argument syntax where the number has to be given as a single token or brace group. Which is preferable depends on what you are trying to do.
Another example from the latex sources
\def\protected@edef{%
\let\@@protect\protect
\let\protect\@unexpandable@protect
\afterassignment\restore@protect
\edef
}
\protected@edef
takes the syntax of \edef
with delimited arguments etc and restores the meaning of \protect
after the \edef
. So you can do
\protectected@edef\foo#1#2\@nil{.....#1...#2}
It would be rather less convenient to do that without using \afterassignment
.
Another, perhaps better, example again based on usage in the latex base, the following plain TeX file
\def\removetonil#1\xx{}
\def\myset#1{\afterassignment\removetonil
\dimen0=#1pt\relax\xx
\immediate\write20{[\the\dimen0]}}
\myset{3}
\myset{3em}
\myset{3cm}
\myset{\vsize}
\bye
Produces
[3.0pt]
[30.00005pt]
[85.35826pt]
[643.20255pt]
This is setting \dimen0
to a user-specified length where the argument may omit the units (defaulting to pt
) or give explicit units, or be a TeX dimen register or primitive such as \vsize
. By using \afterassignment
the primitive assignment may or may not use tokens after #1
pt\relax
will be used if the argument is a <number>
but not if it is already a dimension. Because \removetonil
is inserted immediately after the assignment it can clear away any unused tokens.