SchemeとActor理論
「最初のSchemeインタプリタは関数とアクターの双方を実装していた」
http://www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/p/frag/frag_f.html
例えば「1と2と3からなるメッセージをアクターaに送る」という事を [a 1 2 3]と書く
新しくアクターを作る事もできる。そのためにはalpha構文を使う。例えば (alpha (u k) [+ u u k])(define _fact (alpha (n k) (if (= n 0) [k 1] [_fact (- n 1) (alpha (u) ; c [k (* n u)])])))http://www.ice.nuie.nagoya-u.ac.jp/~h003149b/lang/actor/actor.html
これにならって、階乗をErlang,Scala,IoのActorで書いてみる。
Erlang版
alpha構文には、spawn(fun()->receive ... end end)が対応する。
-module(fact). -compile(export_all). fact() -> spawn(fun()->receive {0,K} -> K ! 1; {N,K} -> fact() ! {N-1,spawn(fun()->receive R -> K ! (N*R) end end)} end end). main(_) -> fact() ! {4,spawn(fun()->receive R -> io:format("~p~n",[R]) end end)}.
Scala版
alpha構文には、actor{receive{case ... }}が対応する。
import scala.actors._ import scala.actors.Actor._ def fact():Actor = actor{receive{ case (0 ,k:Actor) => k ! 1 case (n:Int,k:Actor) => fact() ! (n-1,actor{receive{case r:Int => k ! (n*r)}}) }} fact() ! (4,actor{receive{case r => println(r)}})
Io版
Ioはもともとメッセージセンドのパラダイムで作られているので、@@はそのメッセージセンドを非同期化するもの、という位置づけ。
関係ないけど、Ioでもパターンマッチが使いたい。
fact := block(n,k, if(n==0,k @@ call(1), fact @@ call(n-1,block(r,k @@ call(n*r))))) fact @@ call(4,block(r,r println)) while(yield,nil)