Erlang プロセス Scheme アクタ
Erlangの根底にある、メッセージを送受しあうオブジェクトという考え方は、
SimulaやSmalltalk、そしてCarl Hewittのアクタモデルだ。
アクタモデルをもとに、SteeleとSussmanがSchemeを作った。
Scheme使いの私としては、Erlangは押さえておかねば。今更ながらに入門してみた。
(FUSEでファイルシステムを作れるようになったから、次はプロセスだ、というのもある)
と、いうわけで、consセルをアクタならぬプロセスで作ってみた。この調子でいけば自然数もプロセスで作れる。
-module(cons). -export([cons/2,atomp/1,car/1,cdr/1,list/1]). rpc(Pid, Request) -> Pid ! {self(), Request}, receive {Pid, Response} -> Response end. % consアクタ cons(X,Y) -> receive % atomp メッセージに false と返事する. {Cont, atomp} -> Cont ! {self(),false}, cons(X,Y); % car メッセージに X と返事する. {Cont, car} -> Cont ! {self(),X}, cons(X,Y); % cdr メッセージに Y と返事する. リストの場合は Y にプロセスIDが入っている. {Cont, cdr} -> Cont ! {self(),Y}, cons(X,Y) end. % アクタにメッセージを送る関数. atomp(X) -> rpc(X, atomp). car(X) -> rpc(X, car). cdr(X) -> rpc(X, cdr). % consアクタを連ねてリストを作る関数. list([]) -> null; list([X|Y]) -> spawn(fun() -> cons(X,list(Y)) end).
-module(test). -import(cons,[cons/2,atomp/1,car/1,cdr/1,list/1]). -export([test_cons/0,test_list/0]). test_cons() -> % consアクタを作る. Cons = spawn(fun() -> cons(hello, world) end), % consアクタにメッセージを送って返事をプリントする. io:format("~p ~p ~p~n", [atomp(Cons), car(Cons), cdr(Cons)]). test_list() -> % consアクタを連ねてリストを作る. List = list([0,1,2]), io:format("~p ~p ~n", [ car(List), cdr(List)]), io:format("~p ~p ~n", [ car(cdr(List)), cdr(cdr(List))]), io:format("~p ~p ~n", [car(cdr(cdr(List))),cdr(cdr(cdr(List)))]).
実行。
Erlang (BEAM) emulator version 5.5.5 [source] [async-threads:0] [kernel-poll:false]
Eshell V5.5.5 (abort with ^G)
1> c(test).
{ok,test}
2> test:test_cons().
false hello world
ok
3> test:test_list().
0 <0.41.0>
1 <0.42.0>
2 null
ok
参考文献:SchemeとActor理論
- 作者: Joe Armstrong,榊原一矢
- 出版社/メーカー: オーム社
- 発売日: 2008/02/23
- メディア: 単行本(ソフトカバー)
- 購入: 8人 クリック: 284回
- この商品を含むブログ (97件) を見る