# What is the difference between \def and \newcommand?

Inspired by a question about \let and \def, I have some that essentially all boil down to asking

What are the differences between \def and \newcommand?

In particular, I wonder

1. Is it possible to have parameters passed to \defed commands, both optional and required?
2. Is there a \redef command equivalent to \renewcommand?
3. I have only ever used \newcommand -- is there any reason I should change that habit?

but I welcome comments on anything else I may not have thought of in this list!

-
 Hi Michael, could you please give the reference to the other question? Thanks! And good question! – Nils Schmidt Jul 30 '10 at 16:29 @Nils: The other question is referenced above; perhaps the formatting makes it harder to see: click anywhere on "\let and \def". – ShreevatsaR Jul 30 '10 at 16:58 I've modified the link to hopefully make it a little more obvious... – Michael Underwood Jul 30 '10 at 18:22 & ShreevatsaR: Didnt see the link before, but now even I am able to recognize it ;-) Thanks! – Nils Schmidt Jul 31 '10 at 14:07


1. \newcommand checks whether or not the command already exists
2. \newcommand allows you to define an optional argument


1. Yes and No. A command defined using \def has to know exactly what its options are, and how they will be presented to it. However, a TeX command can be a bit clever and examine things other than its arguments. The way that optional commands are handled is to look at the next character in the stream and if it is [ then one version of the command is called, whereas if it isn't then another is called. So if you're prepared to do some hackery, then optional arguments are possible via \def, but it isn't half so easy as \newcommand.
2. No. Since \def doesn't check for a command already being defined, you can redefine stuff simply using \def again. To get the checking, you need to use the \@ifundefined command (note the ampersand!).
3. No!

There's probably lots more to be said on the differences, but that's enough from me.

-
What ampersand? – Mark Meckes Jul 30 '10 at 15:46
He means ampersat. – Will Robertson Jul 30 '10 at 16:00
I'd add that \newcommand can't make anything starting \end.... This is because LaTeX uses these names for the end of environments, and wants to 'discourage' you from breaking things. – Joseph Wright Jul 30 '10 at 18:18
Gosh! Until I looked at that link, I didn't understand what you were all talking about. I think there's a mistake in the mapping table in my brain. Hang on: sudo aptitude update brain. – Andrew Stacey Jul 30 '10 at 18:48
@Andrew: did you mean sudo aptitude upgrade brain, by any chance? – SamB Dec 2 '10 at 3:02

Adding to Andrew's already good response, the one thing that \def can do that \newcommand cannot is define commands that take delimiters other than braces. For example, if you want to be able to write \foo<hello> and have the ‘hello’ interpreted as an argument, you can write

\def\foo<#1>{...something with #1...}


You can also have commands that read input up to the next brace, such as

\def\foobar#1#{\framebox[#1]}
\foobar 47pt {hello}


For a combination of the extensibility of \def with the ease-of-use of \newcommand, check out David Kastrup's suffix package. Very handy when you want to define custom markup for your document.

Also look at the LaTeX3 package xparse which takes a more structured and generalised look at how \newcommand should work.

-

One subtle difference is that you cannot define commands starting with end:

\documentclass{article}
\pagestyle{empty}

\newcommand\test{}
\newcommand\endtest{}

\begin{document}
\begin{test}
\end{test}
\end{document}


results in

! LaTeX Error: Command \endtest already defined.
Or name \end... illegal, see p.192 of the manual.


You can always use \newenvironment to achieve this. But the above code doesn't work even when using \providecommand instead of \newcommand.

Why is there no \provideenvironment? According to Frank Mittelbach, it's performance considerations -- saving memory, 20 years ago. But now there's \ProvideDocumentEnvironment from the xparse package. Plus,

Unlike LaTeX 2ε’s \newcommand and relatives, the \DeclareDocumentCommand function do not prevent creation of functions with names starting \end.

-