もうモナドの話題じゃないです。けど、少し引きずってますね; モナド関連で、「左から右」と「右から左」に触れたんですけど、そのことについてです。
ヘブライ語やアラビア語の書字方向(scriptingのdirection)は、右から左に向かう横書きということです。でも、"2006"という年号や"Isac Newton"なんて人名(外国人名になります)は左から右となるので、一行のなかに「右から左」と「左から右」が混じることになります。こんな書き方をバイダイレクショナル(bidirectional)、略してバイダイと形容します。
ヘブライ/アラビア語はたいへんだなー、と思うのだけど、プログラミング言語や数式も実はバイダイなんですよね。例えば、foo(a, b); bar(x);
を考えてみると: 呼び出しの時間順は、foo(a, b);
→bar(x);
だから「左から右」でいいですね。しかし、引数を関数に渡す操作だと、(a, b)
→foo
、(x)
→bar
と「右から左」なんです。もし複数引数の評価順が左から右だと、(a, b)
の部分はa
→b
です。全体の“行きつ戻りつ”は次のような感じ:
評価の時間順序や構文の構成順序を追うとき、目線の移動と塊(部分表現)の把握は次のように進むでしょう。
(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次元に畳み込もうとするから無理が生じるんですよ。折り畳みのシワシワでバイダイになるわけね。