Ruby on ErlangVM in RubyKaigi2015 LT

# 概要
RubyKaigi2015で、John Linさんという方が、ErRubyというErlangVM上で動くRuby実装のLT発表をされてました。興味深い内容でしたのでその紹介をします。

# 基本情報
ざっくりと言うと、ErlangVM上で動作するErRubyというRuby実装を作った(作っているよ)という内容です。

LTのスライドは以下のリンクからどうぞ。
[What I learned by implementing a Ruby VM in Erlang](https://speakerdeck.com/johnlinvc/what-i-learned-by-implementing-a-ruby-vm-in-erlang)

Githubのリポジトリは以下です。
[erruby](https://github.com/johnlinvc/erruby)

目標はRubySpecを通す事だそうです。

# アイデア
「ErlangのProcessをRubyのObjectとして扱えば良いんじゃね?」との事。

|       | Erlang Process    | Ruby Object    |
|:-----:|:-----------------:|:--------------:|
|コスト  |低い,max=134,217,727|低い,全てがObject|
|通信方式|非同期通信          |同期通信         |

# example
簡単ですがRubyとErlangの関数呼び出しの比較になります。
Rubyが ``how_is_sushi?`` を同期呼び出ししているのに対して、Erlangは非同期で呼び出しています。

```rb:ruby_example
class Alice
  def chat_with_bob
    res = bob.how_is_sushi? # 1.invokeして結果を待つ 3.結果を受け取る
  end
end

class Bob
  def how_is_sushi? # 2.Idleで待機、messageを受けたらすしを返す、返したらIdle
    "すしわうまい"
  end
end
```

```erlang:erlang_example
chat_with_bob(Bob) ->
  BoB ! {self(), 'how_is_sushi?'}, % 1.BoBにmessageを送信
  receive % 2.返信を待つ
    {ok, Message} -> Message % 6.返信を受け取る
  end.

bob_loop(State) ->
  receive
    {Sender, 'how_is_sushi?'} -> % 3.messageを受け取る
      Sender ! {ok, "すしわうまい"} % 4.返信する
  end,
  bob_loop(State). %5.待機
```

# Ruby Object in Erlang
Objectに対するメソッド呼び出しは ```{send, <自身のprocess id>, ...}``` のメッセージを送信し、その返却は ```{method_result, <自分のprocess id>, ...}``` のメッセージを送信する事とすると、以下の様になります。

### aliceからbobへの呼び出し
alice -> {send, <alice's process id>, 'how_is_sushi?', []} -> bob

### bobからaliceへの返却
alice <- {method_result, <bob's process id>, "すしわうまい"} <- bob

# self call method の問題
一見上手くいった様に見えますが、自身に対するメソッド呼び出し　```bob.sushi_score``` の場合に問題となります。

```rb:ruby_example
class Alice
  def chat_with_bob
    res = bob.is_sushi_good?
  end
end

class Bob
  def is_sushi_good?
    sushi_score > 90
  end

  def sushi_score
    9001
  end
end
```

```erlang:erlang_example
chat_with_bob(Bob) ->
  Bob ! {self(), 'is_sushi_good?'}, % 1.Bobにメッセージを送信
  receive % 2.Bobからのメッセージを待つ
    {ok, Message} -> Message
  end.

bob_loop(State) ->
  receive
    {Sender, 'is_sushi_good?'} -> % 3.メッセージを受ける
      (self() ! ({self(), sushi_score}), % 4.自分自身(self)にメッセージを送信
      receive {ok, Score} -> % 5.Bobからのメッセージを待ち続ける!!!
        Sender ! {ok, Score > 90}
      end;
    {Sender, sushi_score} ->
      Sender ! {ok, 9001}
  end,
  bob_loop(State).
```

上記の ```sushi_score``` の様に、自分自身に対してメッセージを送信した場合、 ```%5``` の様に自分自身のメッセージを待つ事になるので、この実装ではダメなわけです。

# Ruby Method in Erlang
そこでどうするかというと、「RubyのMethodCallもErlangのProcessにすれば良い」です。

### 呼び出しイメージ

alice -> (spawn new process) -> {receiver, 'is_sushi_good?', arg, env, sender} -> (spawn new process) -> {receiver, sushi_score, arg, env, sender} -> ...

# 実装状況
ErRubyの実装状況としては、
- クラス定義
- ブロック・ローカル変数でのメソッドのeval
あたりまでとの事です。多分に実験的ではありますが、実装的にはなかなか面白そうです。興味のある方はコードを追ってみてはいかがでしょうか。

# その他の実装に関する情報
[ErlPort](http://erlport.org)を使って、ErlangとRubyのブリッジングをしています。
このErlPortをラップしたgemが [erlport-ast_mapping](https://github.com/johnlinvc/erlport-ast_mapping) となります。

# まとめ
今回のRubyKaigiではErlang,Elixir,アクターモデルなど、並行性に関する言及が多くありました。
その中でも特に印象に残ったErRubyについて紹介しました。
スライドにもありますが、まだまだ実験段階のものなので実用には程遠いですが、面白いアイデアのプロダクトなので、今後もwatchしていきたいと思います。