マクロツイーター

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

それでも TeX でプログラミングしたい人のための何か (6)

補足: TeX に関数はないといえなくもない事情

前回の記事では、(戻り値のある)関数を(戻り値のない)手続きに置き換えるという変換操作を行った。そしてそれが必要な理由として

TeX には関数がない

と述べた。ところがこれについて違和感を持つ人がいるかも知れない。何故なら、単純に文字列の置き換えをするだけのマクロは関数のように使えるはずだからである。

\def\xx@akari#1{わぁい#1 あかり#1大好き}
\edef\xx@strA{あかり「\akari{限定水平モード}」}

これで文字列変数 \strA の値は期待通りに以下の文字列になる。

あかり「わぁい限定水平モード あかり限定水平モード大好き」

つまり、次の Lua の「関数」を使ったプログラムと同じ動作になる。

function akari(_1)
  return "わぁい" .. _1 .. " あかり" .. _1 .. "大好き"
end
strA = "あかり「" .. akari("限定水平モード") .. "」"

では、「TeX には関数がない」というのは嘘なのかというと………、そう、嘘である。マクロを関数のように使うことは実は可能である。ただし、そのためにはマクロを完全展開可能であるように実装しなければならない、という条件が付く。そして、他の言語では非常に単純に思えるような処理でも完全展開可能になるように作るのは物凄く難しい(或いは不可能である)というケースが大量に存在するのである。この辺りの話は、このブログの「TeX で何か関数のようなものを」シリーズに詳述されているので、興味のある人は読んでみてほしい。(ただし、そちらの記事は TeX プログラミング中級者向けである。)

芸人実力判定問題で「えるたそ名」の関数(eltaso0.luaeltaso_name() 関数)を TeX で実装する問題を出した。eltaso() 自体が初級者でも何とか実装できる(という解説をしている最中である)のに、あの問題が 2 級相当(思い切り難しい!)なのは、「関数として」(つまり完全展開可能)実装することを要求しているからである。*1くれぐれも、初級者は eltaso_name() を関数のまま TeX で実装しようなどと考えてはいけない。

そういうわけで、少なくとも、

初級者が手の届く範囲の TeX には関数は存在しない

というのは間違いない。しかしながら、完全展開可能であることが前もって判明しているマクロ(例えば上述したような「単純な文字列の置き換えのマクロ」など)だったら利用しても構わないであろう。

*1:桁数が 4 桁から 10 桁に増えたからではない。それで面倒にはなるが本質的に難しくなるわけではないと思っている。(ただし「面倒に耐えられるか」という観点はある。)桁数を増やした一番の理由は、「(完全展開可能でない形で実装した上で)予め全部計算して配列変数に入れておく」というチートを防ぐためである。