I give an answer below saying it's a bug in ifthen package, but I think I'm going to reclassify it as a feature.
In unmodified LaTeX2e \( \nd \) are fragile commands and as such they should be preceded by \protect if used in a moving argument (as the argument of \equal).
\ifthenelse{\equal{\protect\(a\protect\)}{\protect\(a\protect\)}}{\typeout Y}{\typeout N}
does work as intended.
If you load the fixltx2e package part of the core base distribution then \( and \) are made robust so you (and even I) might have expected that \protect is not necessary. However the due to the way \ifthenelse overloads the \( \) syntax to be a boolean logic parenthesis rather than math start, \( is made fragile again. The "fix" below locally gives \(\) robust definitions however due to the "interesting" expansion order implemented in ifthenelse This local redefinition applies to the entire predicate not just the arguments to \equal and so the "fix" is entirely wrong as it removes the ifthenelse definition of \(\) entirely.
Sorry (if you want to take away the green tick I'd understand:-) but unless sleeping on it gives me a better idea, or another contributor has a better idea, I think the only thing I can do is more clearly document in ifthen that if you use the ifthen syntax commands (\(\)\or\and\isodd etc inside an \equals test, then you need to \protect them.
Sorry it's a bug.
\ifthenelse uses delimiters \( and \) to brackets boolean expressions. These are not made safe in the strings used by ifthenelse \equal test. The following inserts a local definition to make things safer,
\let\(\relax\let\)\relax
without this line you get the same error shown in your MWE.
\documentclass{article}
\usepackage{ifthen}
\makeatletter
\long\def\ifthenelse#1{%
\toks@{#1}%
\TE@repl\or\TE@or
\TE@repl\and\TE@and
\TE@repl\not\TE@neg
\TE@repl\OR\TE@or
\TE@repl\AND\TE@and
\TE@repl\NOT\TE@neg
\begingroup
\let\protect\@unexpandable@protect
\def\@setref##1##2##3{%
\ifx##1\relax\z@\else\expandafter##2##1\fi}%
\def\value##1{\the\csname c@##1\endcsname}%
\let\equal\TE@equal \let\(\TE@lparen \let\)\TE@rparen
\let\isodd\TE@odd \let\lengthtest\TE@length
\let\isundefined\TE@undef
\begingroup
\let\@tempa\relax\let\@tempb\relax
\let\(\relax\let\)\relax
\xdef\@gtempa{\expandafter\TE@eval\the\toks@\TE@endeval}%
\endgroup
\@gtempa
\expandafter\endgroup\ifTE@val
\expandafter\@firstoftwo
\else
\expandafter\@secondoftwo
\fi}
\makeatother
\ifthenelse{\equal{a}{a}}{\typeout Y}{\typeout N}
\ifthenelse{\equal{a}{b}}{\typeout Y}{\typeout N}
\ifthenelse{\equal{\(a\)}{\(a\)}}{\typeout Y}{\typeout N}
\ifthenelse{\equal{\(a\)}{\(b\)}}{\typeout Y}{\typeout N}
\stop
This produces
Y
N
Y
N
)
No pages of output.
on the terminal showing the tests worked.
ifthenpackage obsolete?) and [algorithmicx(http://ctan.org/pkg/algorithmicx) usesifthento condition on many levels. For example, using\State \Call{MqOpen}{\protect\(\aleph\protect\)}works. Not exactly sure why\relaxmakes it work though. – Werner Jun 09 '12 at 15:03