置換に関して
昨日書いたのを再掲
- 今、根元のスコープから順に置換していってるけど、これは適切なの?
- →置換したものがさらに置換されるケースを考えて、一番近くにあるルールが一番最後に適用されるのが正しいと考えてこの設計にしたが…
- A: そもそも置換したものをさらに置換するとかすると理解が難しくなるからやめようよ案。変数の解決だって内側から見ていって見つかったらそこで終了じゃないか。(名前の解決だよ派)
- B: ユースケース「外側で\x→\bm xが定義されていて、内側でphix→\bm \phi(\x)を定義する」を考えると、内側から順に適用するべきだ案。さもないと外側で定義したルールを再利用したルールを作る際に\bm xをもう一度書く必要が出てきてしまう(関数の適用なんだから近い側から順次適用が必要だよ派)
- !B: それはルール定義のタイミングでルールの本体にその時点で定義されているルールを適用すればいいんだよ派
- C: (当初の案) ユースケース「外側でEx→\mathbb{E}(x)を定義して、内側の文脈でxが\hat{x}に変わったらx→\hat{x}で『継承&オーバーライド』したい」を考えて外側から…
- !C: それは引数を取るマクロで解決すべき問題。
- Bが正解なのかなぁ
- →置換したものがさらに置換されるケースを考えて、一番近くにあるルールが一番最後に適用されるのが正しいと考えてこの設計にしたが…
で、一晩寝て思ったのは、B案への反論として用意した!Bが正しいのではないかと。
変数の宣言のいらないスクリプト言語において、
print (f(x[1]) + f(x[2])) * (f(x[1]) + f(x[2]))
って書くよりも一時的なローカル変数を導入して
t = f(x[1]) + f(x[2]) print t * t
って書いてあったほうがわかりやすいよね。だったらTeXでもその方がわかりやすいんじゃないか?「短い名前」を「コード上の限定された範囲」で使いたい。それはつまりレキシカルスコープの導入だよね。
っていうことはこれはPythonで言うところの代入文なわけだ。代入文なら右辺が代入文の時点での環境を用いて評価されるのはあたりまえだよね。というわけで!Bが肯定される。
さらに、代入の時点で右辺の名前が評価されるんであれば、実用上「置換したものをさらに置換する」は必要ないんだよね。define \x \a\b した際に\aや\bが定義されているなら、それが置換された上で\xの定義になるので、\xを置換した際にさらに置換を繰り返す必要がない。挙動が変わるのは\xを定義してから\aを定義する場合だが、それを実用的な目的で使うことは考えなくていい。引数のあるマクロを導入するほうが素直だから。
定義した名前を定義したスコープの外に輸出することが必要かどうかは判断出来ていない。それが必要なら、マクロに自分が定義されたときの環境を関連付ける必要があるだろうな。クロージャみたいに。