このブログの更新は Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama

メールでのご連絡は hiyama{at}chimaira{dot}org まで。

はじめてのメールはスパムと判定されることがあります。最初は、信頼されているドメインから差し障りのない文面を送っていただけると、スパムと判定されにくいと思います。

参照用 記事

プログラミング言語や数式はバイダイレクショナルなのだ

もうモナドの話題じゃないです。けど、少し引きずってますね; モナド関連で、「左から右」と「右から左」に触れたんですけど、そのことについてです。

ヘブライ語アラビア語の書字方向(scriptingのdirection)は、右から左に向かう横書きということです。でも、"2006"という年号や"Isac Newton"なんて人名(外国人名になります)は左から右となるので、一行のなかに「右から左」と「左から右」が混じることになります。こんな書き方をバイダイレクショナル(bidirectional)、略してバイダイと形容します。

ヘブライアラビア語はたいへんだなー、と思うのだけど、プログラミング言語や数式も実はバイダイなんですよね。例えば、foo(a, b); bar(x);を考えてみると: 呼び出しの時間順は、foo(a, b);bar(x); だから「左から右」でいいですね。しかし、引数を関数に渡す操作だと、(a, b)foo(x)barと「右から左」なんです。もし複数引数の評価順が左から右だと、(a, b)の部分はabです。全体の“行きつ戻りつ”は次のような感じ:


(foo←(a→b))→(bar←a)
評価の時間順序や構文の構成順序を追うとき、目線の移動と塊(部分表現)の把握は次のように進むでしょう。

// foo(a, b)を認識する
a→b→(a, b)→foo→foo(a, b)
// bar(x)を認識する
x→bar→bar(x)
// 全体を認識する
foo(a, b)→bar(x)→foo(a, b); bar(x);

けっこう複雑です。が、慣れてしまっているから大丈夫なのでしょうか? 入れ子の式になると、そんなに簡単ではありません。次の式の評価順序と構造を一瞬で把握できますか。


foo(foo(a, bar(b)), zot(bar(bar(x)), baz(y, z, u)))

全部、左から右に統一してしまえば:


((a, b bar) foo, (x bar bar, (y, z, u) baz) zot) foo

これなら読みやすいかっていうと、そうでもありません。我々はある程度のバイダイに慣れているので、「左から右」や「右から左」に統一されても快適とはいかないようです。

この問題はけっこう深刻です。僕は、バイダイで混乱して間違えることがしょっちゅう。[追記]それが証拠には、入れ子の式を僕書き間違えていたもんね。最初、次のように書いていた→foo(foo(a, bar(b)), zot(bar(bar(x))), baz(y, z, u))、意図と違う。[/追記]ひとつの解決法は図式を使うことです。


foo
/\
/ \
foo zot
/\ / \
a bar bar baz
| | /|\
b bar y z u

x

こんな図形を、無理に1次元に畳み込もうとするから無理が生じるんですよ。折り畳みのシワシワでバイダイになるわけね。