[追記 21:12]前にこれを書いていたこをすっかり忘れてた。なのでタイトル変更。
さて、TeX 言語での「完全展開可能」の話が済んだので、expl3 についての話を始めよう。以前に述べたように、expl3 の言語では「完全展開可能」を 2 つの細分している。
expl3 の言語における「完全展開可能」の定義
先日述べた「TeX 言語での定義」を再掲する。(ただし 1 つ条件を追加した。)
当該のマクロ
\Macro
について、以下の事項が(人為的に)決められているとする:
- どういう引数が「正しい」のか?
- 「正しい引数」の各々について、
\Macro
にそれが伴った場合の「正しい結果」のトークン列は何か?
(※ただし、「正しい結果」のトークン列は「展開可能なトークン」を含まないものとする。)この前提のもとで、
\Macro
に「正しい引数」が伴った任意のトークン列 S について、S を完全展開して生成されるトークン列 T が S に対する「正しい結果」と一致する。
その上で、expl3 の 2 つの「展開可能」は以下のように定義される。
あと残っているのは、「(expl3 での意味の)完全展開(full expansion)」の定義だけである。expl3 で「トークン列を完全展開する」とは以下の操作を意味する。
トークン列の先頭にあるトークンが展開可能なものである間、それを展開することを反復する。
例
(以降、expl3 の用語に合わせる。)
この用語の使い方は expl3 で導入されたものであるが、2 つの「展開可能」の区別自体は従来の TeX 言語のマクロにも適用できる。*1例えば、先日の記事で例として挙げた(制限付展開可能な)\xx@is@empty
が完全展開可能かを調べてみる。空トークン列を引数に与えたものを完全展開するとどうなるか。
\xx@is@empty {} →\ifx \xx@uniq \xx@uniq T\else F\fi →T\else F\fi 〔if-分岐進入〕
網羅展開の場合と異なり、先頭が展開不能な文字トークンになっているので、完全展開はここで止まってしまう。従って、これは完全展開可能の条件を満たさない。
この場合、完全展開可能にするには例えば T/F の前に \expandafter
を置くとよい。
\def\xx@is@empty#1{% \ifx \xx@uniq#1\xx@uniq \expandafterT% \else \expandafterF\fi }
これで、先頭トークンの展開を繰り返すだけで「正しい結果」に至ることができる。(\expandafter
が「展開」される時には、結果的に後方で展開が起こることになるが、展開されたのは飽くまで \expandafter
自体である。)
\xx@is@empty {} →\ifx \xx@uniq \xx@uniq \expandafter T\else \expandafter F\fi →\expandafter T\else F\fi 〔if-分岐進入〕 〔\expandafter があるため「\else F\fi」が展開される〕 →T 〔if-分岐脱出〕