lenv)もRubyオブジェクトだからdRubyで飛ばせるじゃん。見るC-Lindaのeval()このブログを見てる人たちにはおなじみのタプルスペースの話。rd、そしてプロセスを起動するevalです。outはタプルをタプルスペースに書きます。inはパターンで指定したタプルを取り出します(タプルスペースから取り除かれます)。rdはinと同様ですが読むだけでタプルスペースは変化しません。rdpは待ち合わせをしないバージョンのinとrdです。*1最後のevalが曲者で、実引数の評価(計算?)を別プロセスで行い、全ての実引数の評価結果から成るタプルをタプルスペースに書きます。evalをコールした側には直ちに制御が戻ります。同時にN個のプロセスを生成し、それぞれの結果を待ち、その結果をタプルスペースに書くこと別プロセスが生まれるのです。これって相当ゴージャスな感じがします!以下、C-Lindaの擬似コード。なんらかのサーバーを起動するならこんなの。server()という関数を実行するプロセスが一つ生成されます。eval(sever());なにかの演算をさせておくならこんなの。"fib"と100とfib(100)を評価するプロセスが三つ生成されて、全てが終わるとタプルを書きます。?result);こういうのも動くはず。prime(200));Nプロセスで格子状の計算をするならこう。}RindaのevalRuby版LindaことRindaには標準にはevalがありませんが、MoreRindaを使うと、rinda_evalが追加されます。placeはタプルスペース。ブロック引数が子プロセスで実行され、その結果はplaceにwriteされる。サブプロセス側からは、親プロセスのタプルスペースはtsという仮引数で操作できる。endendRubyでは実引数は呼び手のコンテキストで評価された後に渡されますから、C-Lindaのeval()のような見た目にはなりません。代わりにブロック引数をforkした子プロセスに実行させることにしました。機能としては同じようなことができますが、見た目がだいぶ違います。これじゃforkのラッパーにしか見えませんね。テキストこの商品を含むブログを見るそこでMinRubyです!こちらはインタプリタの挙動を好きなように変えられます。takeはpと同様に普通のbuiltinメソッドとしてgenvに登録すればいい。evalは評価方法を変えたいのでifやwhileみたいなスペシャルフォームにしたいところだけど、min_ruby改造するのもアレなので、とりあえずメソッド種にbuiltinとは別のマークをつけることにしました。}func_callで種類がx-builtinのとき、関数コールではなくプロセス生成に変更します。現在の実装ではこのあたりからブートストラップ不可能になっていきます。lenv)をタプルスペースに書きます。これがワーカーへの指示になります。その後、ワーカーが書く予定の結果のタプルをtakeして全ての引数分の結果が集まったら、それをタプルスペースに書きます。リテラルは特別扱いしたけど、もしかすると変数参照も特別扱いするべきかも。endワーカーに処理を依頼するタプルは次のように設計しました。nil]:x_evalはタプルのおおまかな識別子。@nodeはプロセス固有の乱数です。keyはコンテキストのハッシュ値です。ぶつかっちゃうかもしれないけど、今は実験だから気にしない。連番でも乱数でもいい。genvを渡すってことは、定義されている関数全部飛ぶってことなので、けっこうゴージャスだ!以下は10年前に情報処理に載せたNQueens問題をMinRubyで書き直したやつ。return使えないのツライ。nq2()の実行は別プロセスで行われる。evalの結果を待つ。順序に意味がないのでおわった順に集める。Lindaでタプルを生成する操作にはoutとevalの...2010-09-19Rinda::TupleSpaceとNjetNjetは===の結果を反転するだけの小さなクラスです。注目記事リンクgithubウィッシュリスト待ってます最新記事n月刊ラムダノートに寄稿しました。gemを動くようにした話(誰か引き取って月別アーカイブはてなブログをはじめよう!m_sekiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。