マクロツイーター

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

expl3な言語で完全展開可能な関数(マクロ)を作る件について (4)

再びナベアツの話

「TeX なんかやめて expl3 を使えば!?」の記事で \NabeAzzX の expl3 の言語での実装を掲載した。続いて本シリーズ第 1 回における補足説明の記事の最後で、\NabeAzzX の実装の中で使われている \prg_stepwise_function:nnnN は完全展開可能(★ 印)でなく制限付展開可能(☆ 印)であると述べた。(それ以外で使われている関数は全て完全展開可能である。)ここまで読んだ人なら、これが意味するところは明らかであろう。\prg_stepwise_function:nnnN\NabeAzzX(=\zrxxnz_x_main:n)の本体の最も外側で使われている。これが完全展開可能でないということは、\NabeAzzX も完全展開可能ではない。しかし既に見たように \edef による展開(これは網羅展開である)で正しい結果に至っていて、従って、\NabeAzzX は「制限付展開可能」であったことが解る。*1

\NabeAzzX が完全展開可能でないことは、前回に登場した \exp_args:〜 を利用して次のようにして確かめられる。\NabeAzzX のプログラムが読み込まれた状態で次の文を実行する。

\exp_args:Nf \tl_show:n { \NabeAzzX { 40 } }

結果の画面出力、すなわち \NabeAzz{40} を完全展開した結果は次のようになる。

> {\int_to_arabic:n {1}}\c_space_tl \exp_args:NNf \prg_stepwise_aux:NnnnN >{\in
t_eval:n {1+1}}{1}{40}\zrxxnz_process_step:n \prg_break_point:n {}.
\exp_args:Nf ...ter:wN {\tex_romannumeral:D -`0#2}

\NabeAzz{40} の展開が、その「正しい出力の先頭のトークン」である { を生成したところで止まっていることが解る。

もちろん、今の \NabeAzzX の場合はそもそも制限付展開可能であればよかったので、\prg_stepwise_function:nnnN が完全展開可能でないことは問題にならない。しかし、これが原因で行き詰まってしまうこともある。それを次回以降で紹介する。

*1:TeX 言語で普通「完全展開可能」というのは expl3 の「制限付展開可能」の意味であることを思い出そう。