# No \makeatletter required?

In typing up some small examples that might create errors in LaTeX (for Documents with typical LaTeX errors), I tried the following:

\documentclass{article}
\def\my@macro#1{-#1-}% This is magic
\begin{document}
\my@macro{hi}% Print -hi-
\end{document}


Since I almost religiously encompass @-symbol definitions and/or usage with \makeatletter and \makeatother (see What do \makeatletter and \makeatother do?), and since latex.ltx issues \makeatother at literally the 4th-to-last line, I thought this would flash an error.

It didn't.

Not only was I able to define the macro, I was able to use it without problem after it is defined. Why is this the case?

One clue here, although I don't know why, is that I'm using the TeX \def syntax, rather than \newcommand, which does produce an error.

-
Jep thats true. (pdflatex utd) When i add a @ somewhere between begin/end {document} it gets printed. So in fact it seems to be a letter. Maybe a change in pdflatex? –  bloodworks Jan 6 '12 at 23:39
@bloodworks nope @ is not a letter but a symbol just like 1 or / etc. And yes symbols print but they can't be used in macros "names". they can however be used inargument delimiters when using \def to define macros. –  Frank Mittelbach Jan 7 '12 at 0:05

Your definition defines a macro \my that is required to be followed by @macro followed by one argument (which is either a single token or a brace group). Thus this gives you the result.

Reason that this works this way is that normally @ is not a letter (but a symbol which is \catcode 12) so it would end the "macro name" but it then becomes part of the parameter text which is everything that is follows after the name up to the { which starts the replacement text. You can test this as follows:

\show\my
\my @macro {hi}  % should work too
\my {hi}         % error


LaTeX 's \newcommand complains as it builds up the macro definition differently and doesn't allow for delimited arguments.

-

You are defining the control sequence \my which has a bizarre <parameter text> consisting of the tokens

@12 m11 a11 c11 r11 o11 #1

(as subscripts I've put the category code).

This means that \my must be followed by @macro and then comes the argument.

You can experiment writing, after \begin{document},

\my @macro{hi}
\def\my@differentmacro#1{#1!}
\my@differentmacro{Uh}
\my@macro{ERROR}


The first line will be accepted and print

-hi-

because spaces after control sequence names are always ignored.

The second line will be accepted and perform the requested definition; the third line will print

Uh!

while the fourth will give an error:

! Use of \my doesn't match its definition.


Indeed \my now requires @differentmacro after it.

What's the business? If the category code of @ is 12 (\makeatother), then the scanner during \def\my@macro#1{-#1-} will stop the control sequence name as soon as it finds @ which is a non letter (letters have category code 11), so it takes everything up to the first brace as the <parameter text>.

When \makeatletter is in force, @ is a letter, so with

\def\my@macro#1{-#1-}


the macro's name will be \my@macro and the parameter text will be simply #1.

-
+1 for the example with \my@differentmacro. That was what got me to understand how this works. –  Tomas Lycken Jan 7 '12 at 5:54