What's the purpose of nesting a \def within a \newcommand?

It may provide an unconditional setting of content that has a one-time use. Consider the following example:

enter image description here

\documentclass{article}

% ==============================================

% These is defined inside some class/style file
\newcommand{\booktitle}[1]{\def\booktitle{#1}}
\newcommand{\bookauthor}[1]{\def\bookauthor{#1}}
\newcommand{\ISBN}[1]{\def\ISBN{#1}}

% ==============================================

\booktitle{My title}
\bookauthor{The author}

\begin{document}

\setlength{\parindent}{0pt}% Just for this example

Book title: \booktitle{}

Book author: \bookauthor{}

ISBN: \ISBN{}

\end{document}

In the above example, the user only supplied a \booktitle and \bookauthor, but not an \ISBN. However, if we supply an empty argument to each macro when we use it in the document body, it displays as empty or whatever was supplied by the user.


A more common use is typically seen with titles, where

\newcommand{\title}[1]{\def\@title{#1}}
\newcommand{\author}[1]{\def\@author{#1}}

so there is internal access to \@title and \@author. Additionally, one can test whether the user supplied some \title{<title>} and/or \author{<author>} by checking whether or not \@title/\@author exists using (say) \@ifundefined.


Does it really have that? I couldn't find any instances via google except for this question. some journal classes, eg jss.cls have

\newcommand{\ISBN}[1]{\def\@ISBN{#1}}

which is much more reasonable, and I expect (hope!) the code you found was intended to be of that form, and is an error in the class.

As shown, it's legal as Werner explains but it is a terrible user interface. Not because the command is redefined, but because it is redefined with a different argument structure, so the command takes a different syntax depending on whether it has been previously used, which is a poor design even if it works as intended.

There are uses for self-defining macros for example the following which makes a list defining itself to add a comma separator after the first use.

enter image description here

\documentclass{article}

\newcommand\foo{\theenumi\def\foo{\refstepcounter{enumi}, \theenumi}}


\begin{document}

 like this {\foo}

 or this {\foo\foo\foo}

 or this {\foo}

 or this {\foo\foo\foo}

\end{document}

Note there is nothing too special about \def inside \newcommand: the same could be done with \def inside \def or \renewcommand inside \newcommand but of the three \def inside \newcommand is probably preferable as you check the top level command isn't clashing with another package, but you omit the checks on the inner definition which you know is always a re-definition.

Tags:

Macros