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

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

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

参照用 記事

イミュータブル・データとミュータブル・オブジェクトの境界線

再び向井さんからトラックバックをいただき、その向井さん記事から参照されているjijixiさんの記事も拝見しました。なるほど、fold を使うのはカッコイイですね。でも、僕のモヤモヤした感じは晴れません。

僕が話題としているのは、ディクショナリとかセットとかのコレクション系データです。コレクション系データは、その実装がイミュータブルであれ、心理的モデルは変更可能なストレージでしょう(後で詳論)。そのようなデータへの操作とは、変更コマンド(ミューテータ)を時間軸に沿って、次々と送り込むことです。少なくとも僕の感覚としてはそうですね。

関数型言語の純度が高ければ高いほど、“時間軸に沿った変更”を直接的には扱いにくくなります。処方箋は、時間を空間に変換してしまうことです。例えば、時間軸に沿って順次発生するイベント列 foo, bar, baz をリスト [foo, bar, baz] で表現するとか。

これ、手法として素晴らしいですが、「やっぱり、時間は時間だろうや」という感覚を僕は払拭できません。その意味では、“コレクション・データと変更コマンド”を、“プロセスとメッセージ”で表現する向井さんの提案は心理的しっくりきます。

と、ここまで書いて自分でハタと気が付いたのだけど、論点は全然テクニカル/フォーマルなものじゃなくて、心理モデルのほうかも知れない。つまり、心情的にイミュータブル(時間概念なし)であるべきモノと、ミュータブル(時間概念あり、状態とアイデンティティを持つ)でいいモノの境界線問題が議論の背景だったのではないか。話題にしていたコレクション・データが、境界線付近の微妙な位置にいた*1、って、そういう事情だな、たぶん。

で、心情的な話だと割り切った上で; ディスクファイルへの書き込み、次のように書くと違和感持つ人いるのでしょうか?


sample() ->
{ok, F} = file:open("greeting.out", [write]),
file:write(F, "Hello, "),
file:write(F, "World.\n"),
file:close(F).

もし仮に(思考実験ね)、「ファイルもディクショナリ(dict)やセット(gb_sets)のように、イミュータブルのごとく振る舞うべし」となると(単純化のため、オープン時エラーとクローズを無視):


sample() ->
F0 = file:open("greeting.out", [write]),
F1 = file:write("Hello, ", F0),
F2 = file:write("World.\n", F1),
ok.

これをfoldで書き直すと:


sample() ->
lists:foldl(fun(Msg, F) -> file:write(Msg, F) end,
file:open("greeting.out", [write]),
["Hello, ", "World.\n"]),
ok.

ウーム…。心情的には、シロウト用の構文糖衣かモナドのほうがいいなー、と思う、あくまで心情的なハナシだけどさ。

P.S. 皆さん、どのような心情をお持ちでしょうか?

*1:dictとgb_setsの使い勝手と実装方法がまったく違っていたことは、その証拠の一つでしょう。