Why doesn't this code combining \foreach with \newtheorem work?
The commands in the final argument of \newtheorem
are expanded as each theorem is set not at the point of definition, so each theorem tries to use the command \x
in its title, long after your loop has finished. You need to change the order of evaluation, for example this works:
\documentclass[a4paper]{amsart}
\usepackage{pgffor}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\foreach \x in % 1
{conjecture, definition, example} % 2
{\edef\tmp{\noexpand\newtheorem{\x}[baseTheorem]{\noexpand\MakeUppercase{\x}}}\tmp} % 3
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
While David Carlisle has given the technical reasons for your problem (\x
is expanded to late) in his answer, you can also use the .list
handler that uses \foreach
internally but
- doesn’t group its content (not a problem here because
\newtheorem
defines the environments globally anyway) and - can be used with the already expanded content as
#1
(rather than as a macro sequence).
Code
\documentclass[a4paper]{amsart}
\usepackage{pgffor}
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\pgfkeys{/utils/my Foreach/.code={\newtheorem{#1}[baseTheorem]{\MakeUppercase{#1}}},
/utils/my Foreach/.list={conjecture, definition, example}}
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}
As David has already explained, you need to get the strings, not \x
which expands to the strings. It's easy with expl3
.
\documentclass[a4paper]{amsart}
\usepackage{expl3}
\ExplSyntaxOn
% provide a "user interface"
\cs_set_eq:NN \Foreach \clist_map_inline:nn
\ExplSyntaxOff
\theoremstyle{definition}
\newtheorem{baseTheorem}{Base Theorem}[section]
\Foreach{conjecture, definition, example}
{\newtheorem{#1}[baseTheorem]{\MakeUppercase{#1}}}
\begin{document}
\section{Even numbers}
\begin{definition}
A number is called \emph{even} if its remainder on division by $2$ is zero.
\end{definition}
\begin{example}
$2$ and $0$ are both even numbers.
\end{example}
\begin{conjecture}
The sum of two even numbers is again an even number.
\end{conjecture}
\end{document}