This question is motivated as a followup to this one, where I ran into an issue with subtle differences in execution order between a usepackage command and AtBeginDocument. To simplify the discussion, I'll reproduce the main code here:
\documentclass{report}
\AtBeginDocument{\listoffigures}
\usepackage{cleveref}
\begin{document}
\begin{figure} \caption{This caption cross-references \cref{eqn}.} \label{fig} \end{figure}
\begin{equation} F = ma \label{eqn}\end{equation}
\end{document}
Paraphrasing a comment I posted in response to the answer there, my assumption from the naming was that \AtBeginDocument would behave like a preprocessor macro in C or something similar to that, i.e. it would be lazily expanded and evaluated when it was run (at the beginning of the document). However, the issue I ran into was caused by running a \usepackage command in the preamble of my document after \AtBeginDocument was called in my cls file, and it was resolved when I moved the usepackage call above AtBeginDocument, indicating that it's immediately executing the commands but somehow delaying their effect until \begin{document}. Specifically, this order led to cleveref not knowing how to refer to equations in the figure captions copied into the lof:
\AtBeginDocument{...}
\usepackage{cleveref}
whereas swapping those two commands fixed that issue. So my question is, how does \AtBeginDocument work, and what assumptions can I actually make about when its arguments are evaluated and when their side effects will become apparent?
\AtBeginDocument{<stuff>}would just append<stuff>to a hook that is executed at\begin{documen}. So\AtBeginDocument{<A>}\AtBeginDocument{<B>}would execute<A>and then<B>at\begin{document}. Since some packages use\AtBeginDocumentyou can sometimes get different results when you move\AtBeginDocumentbefore or after a\usepackage. But the LaTeX version released tonight (LaTeX 2020-10-01) has a much more sophisticated hook mechanism that makes it possible to have finer control over\AtBeginDocument. – moewe Oct 03 '20 at 11:48\AtBeginDocument{\listoffigures}might be a bit dangerous. I'm not sure if\AtBeginDocumentis supposed to contain typesettable content. Usually it contains setup and config code. – moewe Oct 03 '20 at 11:54etoolboxsuggests\AfterEndPreamble(which probably has a 'native' LaTeX hook equivalent in the 2020-10-01 release). – moewe Oct 03 '20 at 11:57cleverefcode to find out what is actually going on here, but I know thatcleverefuses\AtBeginDocumentquite extensively. So I'd guess if you say\AtBeginDocument{\listoffigures}\usepackage{cleveref}the begin document hook contains\listoffigures <cleveref initialisation code>and if you say\usepackage{cleveref}\AtBeginDocument{\listoffigures}you get<cleveref initialisation code> \listoffigures. The latter gives the expected result, the former doesn't if\litsoffiguresusescleverefcommands. – moewe Oct 03 '20 at 12:01