7

Note: I have seen a seemingly duplicate question at Why I can not define commands starting with \end? that offers a workaround but does not really answer the "Why" part of the question. This question is meant to really understand the "Why" part.

Example code:

\documentclass{article}
\newcommand{\endnote}{endnote}
\begin{document}
hello
\end{document}

Output:

$ pdflatex foo.tex
This is pdfTeX, Version 3.14159265-2.6-1.40.21 (TeX Live 2020) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./foo.tex
LaTeX2e <2020-10-01> patch level 4
L3 programming layer <2021-02-18>
(/usr/local/texlive/2020basic/texmf-dist/tex/latex/base/article.cls
Document Class: article 2020/04/10 v1.4m Standard LaTeX document class
(/usr/local/texlive/2020basic/texmf-dist/tex/latex/base/size10.clo))

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

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.2 \newcommand{\endnote}{endnote}
                                  
?

The error messages asks me to read page 192 of manual. But I could not understand which manual it is referring to. I would like to know exactly why LaTeX refuses to create a command that begins with \end.

2
  • 3
    It seems to be a protection built in by \newcommand, since all environments create a macro \end<environmentname>, your definition, if executed, would overwrite a hypothetical environment named note. You can \def\endnote{}, but you do so at your own risk. Commented May 25, 2021 at 12:14
  • 1
    @StevenB.Segletes +1 from me. Btw: In the context of macros \<environmentname> and \<endenvironmentname> underlying environments I especially like the environments csname and group. ;-)) Commented May 27, 2021 at 14:11

2 Answers 2

9

When an \newenvironment is defined, two macros are created. As an example, consider an environment named note. The two created macros are \note and \endnote. Thus, any environment created will have a macro associated with it that begins with \end.... Novice users may not realize that the creation of an environment named note ties up a macro named \endnote.

This answer may explain the dangers of allowing \end... as a macro name. If issued after the creation of a corresponding environment, it ruins the environment. If issued before the creation of a corresponding environment, the macro gets overwritten.

Thus, my speculation is that \newcommand expressedly forbids it, to avoid this confusion since, to the novice, there may not seem any connection between a macro named \endnote and an environment named note.

\documentclass{article}
\newenvironment{note}{Note:}{The End}
\begin{document}
\begin{note}
Hi mom
\end{note}

\def\endnote{endnote}
\endnote

\begin{note}
Hi mom
\end{note}

\end{document}

enter image description here

0
3

Often environments are defined by means of the \newenvironment-macro whereby the underlying macros \⁠⟨environmentname⟩ and \end⁠⟨environmentname⟩ are defined.

If an environment is defined this way, then the \begin-macro beneath other things opens up a new scope/group and within that scope/group calls the macro \⁠⟨environmentname⟩ via \csname ⁠⟨environmentname⟩⁠\endcsname.

If an environment is defined this way, then the \end-macro beneath other things calls the macro \end⁠⟨environmentname⟩ via \csname end⁠⟨environmentname⟩⁠\endcsname and afterwards closes the scope/group opened up by the \begin-macro.

\csname ⁠⟨macroname⟩\endcsname delivers the token \⁠⟨macroname⟩. In case the token delivered is not already defined at the time of delivery by \csname..\endcsname, it will be defined equal to the \relax-primitive within the current scope/group. (The \relax-primitive is a non-expandable no-op which makes it into TeX's stomach.)

A token being undefined or being defined equal to the \relax-primitive is the same for \newcommand: If you do \let\foobar=\relax, then you can afterwards perfectly do \newcommand{\foobar}... without getting an error about \foobar being already defined. Actually \newcommand doesn't check if the command to be defined is undefined. \newcommand actually checks if it is the case that the command to define either is undefined or equals \relax. If this is the case, the definition will be performed. If this is not the case, i.e., if the command to define is defined different to \relax, then an error-message about the command in question being already defined is raised.

If a macro \end⁠⟨environmentname⟩ was defined for every environment, then \newcommand forbidding the defining of macros with the phrase "\end" in their name would not be necessary. Checking for (underlying) macros already being defined different from \relax would be sufficient both with \newcommand and with \newenvironment.

The \newenvironment-macro is a nice tool for defining environments but actually the \begin-macro and the \end-macro "don't care" how the defining of underlying macros \⁠⟨environmentname⟩ and \end⁠⟨environmentname⟩ was done.

Sometimes environments are defined not by using \newenvironment but by just defining the underlying \⁠⟨environmentname⟩-macro directly while leaving the \end⁠⟨environmentname⟩-macro undefined, relying on the circumstance that invocation as \csname end⟨environmentname⟩⁠\endcsname via the \end-macro would yield the \relax-no-op as within the scope/group of the current environment the macro \end⁠⟨environmentname⟩ is undefined.

Thus forbidding the defining of macros with \end... in their name prevents accidentally/erroneously defining an \end⁠⟨environmentname⟩-macro for an environment where none should be defined.

5
  • Do you have an example of a environment that does not define its own \end<environment> ? Commented May 27, 2021 at 16:00
  • 1
    @StevenB.Segletes \begin{small} ... \end{small} :) Commented May 27, 2021 at 16:15
  • @StevenB.Segletes E.g., the environment comment of the package "comment". :-) (Defining macros \environmentname but not defining macros \endenvironmentname is a common thing with environments that process things under verbatim-catcode-régime until encountering a sequence of character-tokens e, n, d, {, ..., }.) Besides this it is perfectly legal to use, e.g., font-changing-commands like \large as environments \begin{large}...\end{large} although \endlarge is undefined. Commented May 27, 2021 at 16:17
  • Fasinating...so it is just a glorified scoping mechanism for an existing declarative (i.e., argument-free) macro. Commented May 27, 2021 at 16:30
  • 1
    @StevenB.Segletes There comes some useful infrastructure with that scoping mechanism. E.g., error-messages. E.g., macros/switches for vertical spacing before and after the environment, paragraph-breaking after the environment, an environment-specific variant of \@esphack etc. ;-) Besides this - if the environment is to process arguments, then the underlying \<environmentname>-macro is not necessarily argument-free. ;-) Commented May 27, 2021 at 22:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .