Why is the \bye command not used by LaTeX?

There are syntactical reasons. LaTeX has the concept of environments, not present in plain TeX. The environment document is the outer environment of the document contents.

The setup/configuration of the document is separated from the actual document contents and this is done in the preamble before the environment document starts. The preamble loads the class and packages, which is not allowed in environmentdocument.

Also \begin{document} introduces the concept of document initialization, again not present in plain TeX. For example, the .aux file is read in \begin{document} (and again checked in \end{document}.

The environment form enforces proper nesting of environments:

\begin{document}
  \begin{table}
    \begin{quote}
      \begin{tabular}{l}
        % Compare \bye vs. \end{document} here
      \end{tabular}
    \end{quote}
  \end{tabular}
\end{document}

If \bye is the normal form of ending a document, then it can be written inside other environments in a syntactically correct appearance, see the previous code. But the wrong place becomes obvious, when written as \end{document}.


Let's look at how \enddocument is defined (see latex.ltx, the LaTeX "kernel"):

\def\enddocument{%
   \let\AtEndDocument\@firstofone
   \@enddocumenthook
   \@checkend{document}%
   \clearpage
   \begingroup
     \if@filesw
       \immediate\closeout\@mainaux
       \let\@setckpt\@gobbletwo
       \let\@newl@bel\@testdef
       \@tempswafalse
       \makeatletter \@@input\jobname.aux
     \fi
     \@dofilelist
     \ifdim \font@submax >\fontsubfuzz\relax
       \@font@warning{Size substitutions with differences\MessageBreak
                  up to \font@submax\space have occurred.\@gobbletwo}%
     \fi
     \@defaultsubs
     \@refundefined
     \if@filesw
       \ifx \@multiplelabels \relax
         \if@tempswa
           \@latex@warning@no@line{Label(s) may have changed.
               Rerun to get cross-references right}%
         \fi
       \else
         \@multiplelabels
       \fi
     \fi
   \endgroup
   \deadcycles\z@\@@end}

A full discussion of what all is being executed would be very tedious. Among the more interesting activities, in my view..., are (a) the \clearpage instruction, which flushes all pending floats, (b) the closing of the aux file, and (c) a check if some cross-references are still unresolved; if there are still-unresolved references, the following famous warning message about needing to rerun LaTeX is generated:

           \@latex@warning@no@line{Label(s) may have changed.
               Rerun to get cross-references right}%

The definition of \bye (see p. 357 of the Texbook) follows a completely different model:

\outer\def\bye{\par\vfill\supereject\end}

Finally, here's the definition of \stop, a macro mentioned in a comment by David Carlisle:

\def\stop{\clearpage\deadcycles\z@\let\par\@@par\@@end}

(\@@end is a LaTeX-internal version of the "primitive" command \end.) Can you tell why David added that "it should never be used in normal [LaTeX] documents"?