マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

頑強とか脆弱とか完全展開可能とか

定義をまとめてみた。

トークンが)展開可能(expandable)
そのトークンが実行対象になった場合に、直接実行されるのでなく、一旦他のトークン列に置き換えられる(「展開される」)こと。展開の際に後続のトークンを含めて置換対象になることがある。例えば、マクロであるトークンは展開可能である(定義本体に置き換えられる)。プリミティブはその種類毎に展開可能性が決まっている:例えば、\the\number は展開可能であり、一方で \def\hskip は展開可能でない。*1
トークンが)実行される(executed)
展開可能でないトークンが実行対象になって定められた動作を行うこと。例えば、\let だったらトークンの倒置が行われる(この際に後続のトークンが読み込まれる)。トークンが countdef トークン(\@tempcnta 等)の場合、その整数レジスタへの代入が行われる。ただし、展開可能であるトークンが「展開される」ことも「実行される」に含める場合がある。
トークン列が実行される
列が空になるまで、列の先頭にあるトークンを実行(展開も含む)し続ける。例えば、\count@ の値が 42 の時に、「\the \count@ \advance \count@ \@ne \the \count@」を実行すると、「4243」というテキストが出力される。(「4243」というトークン列に「展開される」のではない。)
展開限定文脈(expansion-only context)
展開可能でないトークンの実行が抑止され、トークンの展開のみが行われる状況。例えば、\edef の実行時には、その定義本体が展開限定文脈となり完全展開が行われる。「実行が抑止された文脈(execution-suppressed context)」ともいう。
トークン列を)完全展開する(full-expand)
展開可能なトークンがなくなるまで、列の最も左にある展開可能なトークンを展開する操作を繰り返すこと。結果として、展開可能でないトークンからなる列が得られる。例えば、\count@ の値が 42 の時に、「\the \count@ \advance \count@ \@ne \the \count@」を完全展開すると、「42\advance \count@ \@ne 42」というトークン列になる。完全展開の操作が実際に行われるのは展開限定文脈に限られる。
(マクロが)完全展開可能(fully-expandable)
マクロに「正当な引数」を伴ったトークン列を完全展開した結果のトークン列が、「正しい展開結果」と常に一致すること。ここで「正当な引数」や「正しい展開結果」は予め恣意的に決められていることが前提。
トークンが)保護付(protected)
当該のトークンが \DeclareRobustCommand で定義されたマクロを意味する(これを「生来的に保護付(natively-protected)」という)、あるいは、\protect が前に付されている。\protect を付けることを「保護する」という。
トークン列を)保護付完全展開する(full-expand with protection)
保護されたトークンを仮に展開可能でないと見做した状態で、完全展開の操作を行う。\protect を厳密に取り扱うのは難しいが、取りあえず、\noexpand であると思えばよい。
(マクロが)頑強(robust)
マクロに「正当な引数」を伴ったトークン列を保護付完全展開した結果のトークン列を、後で展開限定文脈外で実行した場合に、「正しい動作」が常に行われる。ここで「正当な引数」や「正しい動作」は予め恣意的に決められていることが前提。
(マクロが)脆弱(fragile)
頑強でないこと。

注意しておきたいのは、実はここで述べられている定義は我流であるということである。従って、別の文献を参照すると、ここに挙げたものと食い違う定義が与えられている場合があることに注意されたい。実のところは、これらの用語については、非常に曖昧な、ToL プログラムを作成したい学習者から見るとあまり役に立たない「定義」が与えられていることがほとんどであるように感じている。ここで挙げた定義は、「私はそれを採用してプログラムを書いて、実際に上手くいっている」ものであると理解して欲しい。

*1:「完全展開可能」とは異なる概念である。ただし、特にマクロに関して、「完全展開可能」のことを略して「展開可能」という場合がある。(マクロは自明に「展開可能」であるため。)