檜山正幸のキマイラ飼育記 このページをアンテナに追加 RSSフィード Twitter

キマイラ・サイトは http://www.chimaira.org/です。
トラックバック/コメントは日付を気にせずにどうぞ。
連絡は hiyama{at}chimaira{dot}org へ。
蒸し返し歓迎!
このブログの更新は、Twitterアカウント @m_hiyama で通知されます。
Follow @m_hiyama
ところで、アーカイブってけっこう便利ですよ。

2007-05-18 (金)

Erlangのコレクションと簡易データベース

| 10:06 | 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でコレクション・データ/オンメモリ・ストレージを使いたいときは:

  1. プロセス・ディクショナリ -- お手軽簡単
  2. ライブラリが提供するデータ構造 -- ツリー、セット、ディクショナリなど
  3. 組み込み項ストレージ -- 大容量でミュータブル

といった選択肢があるってことですね。

jmkjmk 2007/05/18 11:10 ありがとうございます。じつはエントリーを書いてトラックバックをうってから「単に辞書だけじゃなくて単一代入形式の話に一般化した問題だからこの回答だけじゃだめだな」と遅まきながら気付いたのですが、時すでに遅しでした。

ごく単純には、ひとつのデータを何度も更新して変数として受け取るのではなく、たとえば再帰などを使ってつねに同じ名前で束縛する、という手はあると思いますが(で、その再帰をプロセスとしておき利用者は外からメッセージを送るとか)、なんというか、根本的にはおっしゃる通りだと思います。

あと、あんまりよく知らないんですが mnesia というDBMSもあるらしいですよ。

m-hiyamam-hiyama 2007/05/18 12:49 jmk(向井)さん、
「うっとうしい、面倒だ、イヤだ」というのも習慣・文化の問題かもしれません。Erlang文化になじめば、そのなかで快適と感じる方法(再帰とプロセスなのか?)があるのかもしれませんね。
> mnesia というDBMSもあるらしいですよ。
名前だけは見たことがあります。現状、僕にとっての最大の疑問は「Mnesia -- なんて読むんだ、これ?」です。

sumiisumii 2007/05/18 13:01 私の耳で聞いた限り「エムネジア」でした。:-)(もちろんamnesiaのダジャレ)

m-hiyamam-hiyama 2007/05/18 17:56 sumiiさん、
「エムネジア」ですか。読み方がわかったら、なんか親しみが持てました。調べてみようかな。

lethevertlethevert 2007/05/19 21:14 あ、あれは「エムネジア」と呼ぶんですか。
ちなみに、初期のころ、ram only dbでシャットダウンするとデータが消えるところからamnesiaという名前がつけられたそうです。
http://d.hatena.ne.jp/lethevert/20061108/p2

sumiisumii 2007/05/19 23:14 あーいや、あくまでICFPやErlangワークショップ等で(エリクソンの人などから)私の耳で聞いた音を、私が日本語の片仮名で書いてみただけなので、「ムニージャ」でも近かったと思います。「ム」の音は確かに聞こえたように思いますが、ひょっとしたら空耳かもしれません。

lethevertlethevert 2007/05/19 23:20 私のは想像なので、実際に聞いた音の方が正確ではないかと思います。
それに、sumiiさんの語学力で空耳はないかと :)

m-hiyamam-hiyama 2007/05/21 08:52 原音に忠実であることが最重要ってわけではなくて、カタカナ表記が定まることに意義があるかと。「エムネジア」にしましょうよ。

トラックバック - http://d.hatena.ne.jp/m-hiyama/20070518