Erlang」カテゴリーアーカイブ

HackerNewsつまみぐい 2015/8/9

Erlang関係のスレッドがチラホラとあった1日でした。

元記事はBEAM(=ErlangVM)についての専門家の紹介とQAっぽい内容です。ただコメント欄はBEAMとJVMの比較で議論が伸びてますね。

元記事はErlangをいく選択すべきか?という内容。CPU負荷が高いのには向いていない、レイテンシースループットが必要な場合は向いているとErlangの本を読むと書いてある内容が羅列されていますが、向いていない項目の中にGlue-together style web applicationというのがあります。Railsっぽいアプリ(つまりDBとフロントがガッツリくっついてる=Glue-together?)はやらん方が良いと書いてあります。

対してHNのコメントで、下記のようなやり取りが行われています。

ffn 16 hours ago
>Erlang is not good for Glue-together style web application
Granted Elixir's Phoenix framework is not Rails level yet, it's system of plugs and heavy inspiration from rails actually makes it quite useable as a replacement for rails. Also immutability and the associated smaller memory footprint makes it more feasible to run cheaply on services like heroku or aws. Personally, I think elixir is a good boat to jump on to carry us over to the next world of web development.
reply
ElixirのPhoenixフレームワークはまだRailsのレベルには達していない。(少し略)Elixirは我々を次のWeb開発の世界へと連れていってくれる良いボートだ。
troutwine 14 hours ago
I wrote this article way back in 2013. Initial commit of Phoenix was Jan 18, 2014.
But! you're quite right. Elixir is focusing on the web application type things that Erlang and the community around it has never much addressed. There's enough interoperability from Elixir to Erlang that you could probably say the ecosystem as a whole is addressing the problem if you squint hard enough.
Side comment, it's been interesting to see Elixir grow since 2013. A lot of folks learn Elixir and then Erlang but I think it's less common to learn Erlang and then learn Elixir. It's led to an interesting situation where Elixir has had to bootstrap knowledge about OTP on its own terms without a large pool of domain experts sitting around. The asymmetry in knowledge--knowing Erlang does not imply knowing Elixir but knowing Elixir implies knowing Erlang--also makes me wonder how the squinting assumption above will shake out long-term. ¯\_(シ)_/¯
(前半部分略)
(だいたいの訳)
- 多くの人がElixirを学びErlangを学ぶ、ただErlangを学びElixirを学ぶ人はあまりいないのではないか
- それはOTPを、Elixir自身の言葉でさらにその領域の熟練者たち抜きで乗り越えるという面白い状況が生まれるのではないか

なるほどね、という感じです。僕もElixirはまだチラッとしか見ていないのですが、OTPの各ビヘイビアをElixir側でラップして提供していたりします。(AgentやTask.Supervisor)
ElixirユーザーがOTPを意識せずに使えるようになるとより敷居が低くなって普及が進むのかもしれません。

ElmでWebsocketを使ってゲームを作ってみた例

説明

ElmでWebsocketを使って、非常にシンプルなネットゲームを作ってみました。

リポジトリこちら

実際に動いているのはこちら ※サーバー側(Erlang)がうまくバックグラウンドで動かせていないせいで、たまーにしかプレイできません。すんません。僕のErlang力不足が原因です…

構成

サーバー側はErlangだけ、クライアント側はElm+Javascript(Websocketのコネクション周り)で作っています。

クライアント側

Elmで作っています。Elmです。Elmですね。

Elmはリアクティブプログラミングというプログラミングパラダイムの上に存在します。なので、常にリアクティブな思考を持って作る必要があります。

ベースとなるシグナルを考える

僕の中でリアクティブプログラミングは、電気回路のイメージがあります。予め作られた回路(Elmで書かれた関数)に、信号(Signal)を流し込み、駆動する。そういう感じです。

入力シグナル

入力シグナルの中に、ユーザーの入力を全て詰め込みました。というのも、foldpでゲームエントリー関数を畳み込んでしまうと、もうそこに別のユーザー入力(つまりシグナル)を入れるのがかなり難しそうだと感じたからです。

入力シグナル部分

このシグナルを、foldpで初期ゲーム状態を与えた状態で畳み込みます。

ゲームシグナル部分

他にもウェブソケットのシグナルを扱わないといけないのですが、やっかいなことにElmのWebSocketを開く関数は

String -> Signal String -> Signal String

という型を持っていて、予め作ったシグナルを渡さないと返り値のシグナルが貰えないようになっています。つまり、シグナルのループが出来ないんです。ちょっと良い説明が出来ないのですが、foldpでWebSocketの返り値を含むような閉じたシグナルを作ると、そこからWebSocketの入力に何かを突っ込むことが非常に難しい感じになります。

じゃあどうしたの?

WebSocketはJavascript側でハンドルし、Portという仕組みを使ってWebSocketへの入力、返り値をそれぞれ独立したシグナルにしました。

WebSocketシグナル部分

これでfoldpで作るシグナルにWebSocketの返り値シグナルを入れても、WebSocketへ自由に入力させることができます。

出力シグナル

Elmからサーバーサイドへは、WebSocketへの入力を行うことで出力を行います。

出力シグナル部分

ゲーム関数

ゲーム関数は、クライアント側の中心となる存在です。この中で、

  • WebSocketから受け取った返り値の処理
  • 各種計算
  • ゲーム状態の遷移

これらの処理を全て行います。

ゲーム関数部分

この中の処理はもう普通の処理です。foldpとかElm特有の処理は出てきません。

まとめ

やっぱりリアクティブを意識するのが重要な感じがします。このゲームでは

  • FPSとなるシグナル
  • サーバー側からのシグナル

という2つの方向性が違うシグナルが有り、現状ではFPSの方で強制的にサーバー側のシグナルを同期させています。ただそのせいでサーバー側からのシグナルを一部取りこぼす(他のユーザーが生成したブロックの情報が同期されなかったり)ことがあるので、なんともどうしたものか…と思っています。

解決策としては、

  • サーバー側でクライアントが必ず受け取ったことが確認できない限りメッセージをキャッシュする
  • サーバー側とクライアント側のメッセージ送受信間隔を同期させる

ぐらいしか思いつきませぬ。

Elmのメリット

最後に、Elmのメリットをいくつか。

モジュールの分割が楽

モジュールを分割するのが楽です。しかもひとつのjavascriptファイルに簡単にコンパイルできるので、保守性が抜群です。

綺麗に書ける

javascriptのグチャッとしたソースコードに精神を削られている人も多いと思います。きっとElmは心の癒やしになるでしょう…