If LaTeX was being written now,
\newcommand{\printit[1]}{#1}
would give an error message that \printit[1]
was not a single token.
The correct syntax is
\newcommand{\printit}[1]{#1}
or
\newcommand\printit[1]{#1}
LaTeX does nothing special to allow both forms, it is just on the general TeX macro syntax rules that braces can be omitted if a macro argument is a single token.
If you pass two (or in this case, four) tokens to \newcommand
then anything that happens is essentially just accidental behaviour, as the system could not really afford the space or time required to catch "unlikely" errors.
As to what happens,
\documentclass{article}
\begin{document}
\newcommand{\printit[1]}{#1}
\show\printit
\expandafter\show\csname\string\printit\endcsname
\end{document}
produces the terminal log
> \printit=macro:
->\@protected@testopt \printit \\printit {0}.
l.7 \show\printit
?
> \\printit=\long macro:
[#1]->#1.
The command defines \printit
to have an optional first argument, although the default value of 0 being supplied was intended as the default value for \newcommand
itself.
it is what makes \newcommand\foo
the same as \newcommand\foo[0]
and define a command with no arguments.
The inner part of the command handling the optional argument is \\printit
which just drops the square brackets.
So
\printit{2}
is
\printit[0]{2}
which is
0{2}
which typesets as 02
\def\new@command#1{% \@testopt{\@newcommand#1}0}
from latex.ltx, i.e. LaTeX tests whether there is an optional argument in the first argument of\newcommand
, i.e.\printit[1]
and returns0
, the{2}
in its usage is not regarded as an argument. You could use\printit
without{}
and it will still print0
, use it as\printit[2]
and it will print2
. In fact you have defined a macro with optional arguments in a non-obvious way\newcommand\printit[1]{#1}
or\newcommand{\printit}[1]{#1}
(The number of parameters to be expected is given in square brackets, outside of the{}
). In case people come across this and are confused by the above syntax.