TeX は実行制御を全てマクロ展開だけで行う言語である。だから展開の仕組みを正しく理解すること(もっと具体的にいえば「\expandafter
をどう使うか」)は、ある程度複雑なプログラムを「思った通りに書く」ために欠かせない。その中でも「条件文と展開との関係」は一番厄介なものだと思う。数学的に「綺麗な」形は次のようなものだろう。
\iftrue〈真〉\else〈偽〉\fi
を一回展開すると〈真〉
になる。\iffalse〈真〉\else〈偽〉\fi
を一回展開すると〈偽〉
になる。
(ただし、「結果が真/偽になる \if
条件」を \iftrue
/\iffalse
で代表させた。((この後、実際の TeX の動作の解説を行うが、「条件部はどんなに複雑(例えば \ifnum\count\the3\day\@gobble?*\string0=\z@
とか)でも一回展開で処理される」ことを予め述べておく。)))
ただこの方法は、場合により後に続くトークン列の大規模な組み換え(ずっと後ろにある \fi
だけを除去する)が必要になるので実装には適切でない。実際の TeX は内部で「条件ネストレベル」と「今のレベルまでの判断の結果」を記憶していて、「不成立である分岐に入った時点でその部分を読み飛ばす」という処理を行っている。((e-TeX では「条件ネストレベル」を \currentiflevel
、「最内レベルの判断結果」を \currentifbranch
というパラメタで参照できる。))だから、\if
-トークン、\else
、\fi
(これを仮に「条件トークン」と総称する)はその内部状態を変える標識として「展開」されなければならない。例えば、典型的な末尾再帰の形式
\def\xx@loop{%
\if〈終了条件〉 〈終了処理〉
\else 〈反復処理〉 \expandafter\xx@loop \fi
}
で、\xx@loop
の呼出の前に \expandafter
が要るのも、呼出の前に \fi
を「展開」する必要がある(そうでないと末尾再帰にならない)からである。
では、条件トークンは実際にはどのように「展開」されるのか。これは TeX の参考書でも書いているものが見当たらない。色々と実験した結果から得た(かつ参考書の記述と矛盾しない)推測は、どうやら次のようになっているらしい。
状況 | 一回展開後 |
---|---|
\iftrue〈真〉 | 【真】〈真〉 |
\iffalse〈真〉\fi〈後〉 | 〈後〉 |
\iffalse〈真〉\else〈偽〉 | 【偽】〈偽〉 |
【真】\else〈偽〉\fi〈後〉 | 〈後〉 |
【真】\fi〈後〉 | 〈後〉 |
【偽】\fi〈後〉 | 〈後〉 |
この表は次のように解釈する。