[Tex/LaTex] Difference between \newbool and \newtoggle from etoolbox package

conditionalsetoolboxmacros

Paul Gaborit's answer to How to detect if option provided via \tikzset uses

  • \newbool to define a new boolean
  • \booltrue to set a boolean, and
  • \ifbool to perform a conditional operation

all from the etoolbox package.
Well, I have been using

  • \newtoggle to define a new toggle
  • \toggletrue to set a toggle, and
  • \iftoggle to perform a conditional operation

also from the same package.

Is there a difference between the two? Is one preferable over the other?


Code:

\documentclass{article}
\usepackage{etoolbox}

\newtoggle{ToggleCondition}
\newbool{BooleanCondition}

\newcommand*{\CheckBoolean}{\ifbool{BooleanCondition}{true}{false}}
\newcommand*{\CheckToggle}{\iftoggle{ToggleCondition}{true}{false}}

\begin{document}

\toggletrue{ToggleCondition}
ToggleCondition is \CheckToggle.

\togglefalse{ToggleCondition}
ToggleCondition is \CheckToggle.

\medskip
\booltrue{BooleanCondition}
BooleanCondition is now \CheckBoolean.

\boolfalse{BooleanCondition}
BooleanCondition is now \CheckBoolean.
\end{document}

Best Answer

\newbool{mybool} is almost the same as \newif, but it checks whether \ifmybool is already defined, which LaTeX doesn't:

\newrobustcmd*{\newbool}[1]{%
  \expandafter\@ifdefinable\csname if#1\endcsname{%
    \expandafter\newif\csname if#1\endcsname}}

There's also \providebool which does nothing if the conditional is already defined.

Similarly, \ifbool is a wrapper around the usual construction

\if...
  \expandafter\@firstoftwo
\else
  \expandafter\@secondoftwo
\fi

with a preliminary check whether the conditional is defined. So it can be used also for primitive conditionals:

\ifbool{hmode}{<something for horizontal mode>}{<something else>}

Instead \newtoggle{mytoggle} is defined by

\newrobustcmd*{\newtoggle}[1]{%
  \ifcsdef{etb@tgl@#1}
    {\etb@error{Toggle '#1' already defined}\@eha}
    {\cslet{etb@tgl@#1}\@secondoftwo}}

so it checks whether the toggle is already defined and, if not, it sets it to "false". The constructed macro \etb@tgl@mytoggle is either \@firstoftwo (corresponding to "true") or \@secondoftwo (corresponding to "false"). When one says

\iftoggle{mytoggle}{<true>}{<false>}

etoolbox simply checks whether the toggle is defined and, if it is, just puts \etb@tgl@mytoggle in the input stream, thus doing "the right thing", because it chooses either <true> or <false> depending if it is \@firstoftwo or \@secondoftwo.

Note that \toggletrue is defined as

\newrobustcmd*{\toggletrue}[1]{%
  \ifcsdef{etb@tgl@#1}
    {\cslet{etb@tgl@#1}\etb@toggletrue}
    {\etb@noglobal\etb@err@notoggle{#1}}}

so it can be preceded by \global: indeed \ifcsdef is expandable, so if the toggle foo is not defined, after \global\toggletrue{foo} we'd remain with

\global\etb@noglobal\etb@err@notoggle{#1}}

which becomes

\global\let\relax\relax\etb@err@notoggle{#1}

that effectively removes the \global by doing a harmless \let (almost harmless, because it can impact on the stack memory, but since there's an error raised anyway, the user will correct it). If instead the toggle \foo is defined, we remain with

\global\cslet{etb@tgl@foo}\etb@toggletrue

so, again,

\global\expandafter\let\csname etb@tgl@foo\endcsname\etb@toggletrue

where \etb@toggletrue is the same as \@firstoftwo. The same holds, of course, for \togglefalse.

Which one to prefer? If you plan to use also the traditional \if... syntax, then \newbool is needed. Otherwise it's just a matter of personal preference.

Both booleans and toggles can be used in boolean expression (\ifboolexpr), so there's no difference for that usage either. Note that \global\booltrue and \global\boolfalse are legal too.

Related Question