# 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 @ sign!).
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. – Loop Space 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 quite important difference, not mentioned in the discussion so far, is:

• \newcommand\foo{...} corresponds to \long\def\foo{...}
• \newcommand*\foo{...} corresponds to \def\foo{...}

What does \long mean? Well, if \myCommand is defined using \long, then its arguments can contain paragraph breaks, like this:

\myCommand{Lorem ipsum

dolor sit

amet.}


If \myCommand were defined without \long, then the code above would generate an error. The idea is, that if you know that your command won't ever need to take arguments containing paragraph breaks, then defining it without \long helps you to catch some situations where you've forgotten a closing brace.


Slight digression. Here is a little example that highlights this particular difference between \newcommand and \def.

The following code prints Not empty ...

\documentclass{article}
\begin{document}
\newcommand\foo{}
\ifx\foo\empty Empty\else Not empty\fi
\end{document}



-
Hi John. A tip: if you directly paste the url of a question/answer, the title will automatically appear. – Claudio Fiandrino May 24 '13 at 13:12
Ah so. Thanks, Claudio. – John Wickerson May 24 '13 at 13:13

Here is a summary of the main points made by the other answers. In each case, click on the ▶ symbols for more details.

• \newcommand is part of LaTeX; \def is part of TeX. []

• \newcommand fails if the command is already defined; \def doesn't. []

• \newcommand provides a convenient syntax for specifying the number of arguments, and specifying a (single) optional argument; \def enables pattern-matching on the form of its arguments, which makes it more general but also less readable. []

• \newcommand can't define a command whose name starts with "end"; \def can. []

• \newcommand defines "long" commands; \def defines short ones. (The arguments of a "long" command can include paragraph breaks.) []

-
I thought I would add this summary because there is no single "definitive" answer here; there are instead several good points raised in different answers. – John Wickerson May 25 '13 at 8:08

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.

-