Daily Archives: May 18th, 2007

Erlang、単一代入と破壊的な変更

昨日の文章を書いてから「ああ、べつに辞書に限った話じゃないからこれじゃ意味ねーな」と遅まきながら気付いたんですが、まあそれはしかたない。その点については
檜山さんから指摘をいただいてしまいました。おっしゃるとおりです。
問題点を抽象的な言葉で書くと、「Erlangは純粋関数型言語で、副作用がない」「しかも更新があった値を同じ変数に格納できない」ということですね。さて、どうするか。
解決策ですが、たとえばループを使うことができます。ループは Erlang では末尾再帰関数を使って書きますが、そうすると自分自身を呼び出すときに違う値を指定すれば、同じ変数に違う値を束縛できる。いわば、引数を状態変数として考え、自分自身を呼び出すのを更新とするわけです。
でも、世の中そんなにループばっかりじゃない。ここでやりたいのは普通の逐次的なプログラムを書くことでした。そこで「状態をもつループ」をほかのプロセスへと切り離してしまいます。メッセージを送るとその時点での状態を参照し、メッセージに従って値を返したり、更新したりできます。
では、コードを示します。
-module(dsets). -compile(export_all). new() -> spawn(?MODULE, loop, [gb_sets:empty()]). loop(Set) -> receive {From, {add_element, V}} -> From ! {self(), ok}, loop(gb_sets:add_element(V, [...]