キマイラ・サイトは http://www.chimaira.org/です。
トラックバック/コメントは日付を気にせずにどうぞ。
連絡は hiyama{at}chimaira{dot}org へ。
蒸し返し歓迎!
ところで、アーカイブってけっこう便利ですよ。タクソノミーも作成中。
2007-05-18 (金)
Erlangのコレクションと簡易データベース
昨日のエントリー「Erlangのとても困ったところ:単一代入の思わぬ弊害」に、向井淳さんからトラックバックをいただきました。ありがとうございます。
「いー」けど「だめ」
向井さん記事は、Erlangのプロセス・ディクショナリ(プロセスに作り付けのディクショナリ)を使えばスッキリと書けるよ、てな内容。
このようにして書けるのでした。いーでしょ。……だめ?
僕が例として挙げた個別特定具体的なアノ問題に関しては「いー」と思います。が、一般的な文脈では「だめ」です。ディクショナリは、時間的に状態が変化しながらもアイデンティティ(識別性、持続する固有性)を持ち続けるデータの典型例として出したものです。そのディクショナリに関しては、たまたまプロセスに組み込まれたものがあってラッキーですが、他の状態を持つ(かのごとき)データ構造ではどうでしょう。
例えば、gb_setsというライブラリ・モジュールがあります。内部構造に General Balanced Trees を使った順序集合の実装だそうです;マニュアルから抜粋:
An implementation of ordered sets using Prof. Arne Andersson's General Balanced Trees.
使い方は次のようになります。
sample() ->
S0 = gb_sets:new(), % セットを生成
S1 = gb_sets:add_element("板東トン吉", S0), % 要素を追加
S2 = gb_sets:add_element("大垣ペケ子", S1), % さらに要素を追加
gb_sets:is_element("板東トン吉", S2). % 要素かどうか調べる
もちろん、関数呼び出しの入れ子で書いてもいいし、あるいは、リストを作っておいて適当な関数で一括処理という手もあるでしょう。が、いずれの方法もうっとうしく面倒に感じます。
「セットだって、がんばればプロセス・ディクショナリで出来るよ」ってハナシもあるかも知れませんが、じゃあ、モジュールgb_setsは何のために存在しているのでしょう。それを使うのが適切な場面があるからこそgb_setsが提供されているはずです。そもそもモジュールdictも、プロセス・ディクショナリで代替困難/不可能な状況のために準備されているのでしょう。
僕の不満は、「コレクション類など、状態とアイデンティティを持つ(かのごとき)データを扱う記法が不格好でイヤだ、構文糖衣でいいからなんとかしてくれ」ってものです。
有向グラフと組み込み項ストレージ
コレクション類といえば、有向グラフ(directed graph)のモジュールもありました。モジュールdigraphです。ディクショナリやセットと同じ使い勝手かと思ったら:
sample() -> G = digraph:new(), % グラフを生成 V1 = digraph:add_vertex(G), % 頂点を追加 V2 = digraph:add_vertex(G), % さらに頂点を追加 V3 = digraph:add_vertex(G), % もっと頂点を追加 digraph:add_edge(G, V1, V2, edge1), % 辺を追加 digraph:add_edge(G, V1, V3, edge2), % さらに辺を追加 G. % このグラフを返す
なんか違いますよ。digraph:new()が返すのは、一種の識別子であり、これを第1引数にしていろんな操作をするようになってます。有向グラフはミュータブルみたい。
僕知らなかったんですけど、Erlangランタイムごとに組み込み項ストレージ(Erlang Built-in Term Storage; ETS)というものがあって、簡易データベースのように使えるようです。コマンドets:i().でEシェルからETS状況を確認できます。有向グラフはこのETSにより実装されていたのでした。
ということは、Erlangでコレクション・データ/オンメモリ・ストレージを使いたいときは:
- プロセス・ディクショナリ -- お手軽簡単
- ライブラリが提供するデータ構造 -- ツリー、セット、ディクショナリなど
- 組み込み項ストレージ -- 大容量でミュータブル
といった選択肢があるってことですね。
- 64 http://reader.livedoor.com/reader/
- 59 http://localhost/~kominesatoshi/
- 32 http://www.jmuk.org/diary/
- 31 http://blog.livedoor.jp/dankogai/archives/50832431.html
- 22 http://b.hatena.ne.jp/m-hiyama-taxon/
- 20 http://d.hatena.ne.jp/
- 20 http://www.jmuk.org/diary/2007/05/18/0
- 18 http://www.google.com/reader/view/
- 16 http://d.hatena.ne.jp/lethevert/
- 13 http://a.hatena.ne.jp/sumii/
ごく単純には、ひとつのデータを何度も更新して変数として受け取るのではなく、たとえば再帰などを使ってつねに同じ名前で束縛する、という手はあると思いますが(で、その再帰をプロセスとしておき利用者は外からメッセージを送るとか)、なんというか、根本的にはおっしゃる通りだと思います。
あと、あんまりよく知らないんですが mnesia というDBMSもあるらしいですよ。
「うっとうしい、面倒だ、イヤだ」というのも習慣・文化の問題かもしれません。Erlang文化になじめば、そのなかで快適と感じる方法(再帰とプロセスなのか?)があるのかもしれませんね。
> mnesia というDBMSもあるらしいですよ。
名前だけは見たことがあります。現状、僕にとっての最大の疑問は「Mnesia -- なんて読むんだ、これ?」です。
「エムネジア」ですか。読み方がわかったら、なんか親しみが持てました。調べてみようかな。
ちなみに、初期のころ、ram only dbでシャットダウンするとデータが消えるところからamnesiaという名前がつけられたそうです。
http://d.hatena.ne.jp/lethevert/20061108/p2
それに、sumiiさんの語学力で空耳はないかと :)