emscripten でドメイン層に型と速度を持ち込む


半分ネタです。できたものはこちら。

デモページもあります。

言語の内訳です。

コンセプト

  • C++ を使ってドメイン層を型安全にモデリングする
    • ドメイン層については次の記事を参照してください。
    • template など使って generic にモデリングしたいところだが、 JavaScript へバインディングする際に実体化させないといけないのでうまみはない
  • UI は React などお好みのライブラリー、フレームワークを使えるように
  • WebAssembly などが対応してくるとドメイン層のロジックがちょっぱやになるという期待

要するにロマンです。

経緯

最近は JavaScript フロントエンドの世界にも型が持ちこまれてきています。チームで開発するにあたっては必須だと思いますし、ひとりで開発する場合も型によってバグが減ります。

最近の関数型言語を追えていないこともあって、静的型付け言語というと個人的にはまっさきに C++ が思い浮かびます。 C のメモリーモデルとキャストは自信を持って「型付けされている」と言いづらいものでしたが、 C++ では意図しない限り型変換で危険な目にあうことはないはずです。

JavaScript にも型チェックをするための flow や型を扱える TypeScript などが出てきたのでそれでやればいいじゃんというのは最もな指摘なのですが、まあなんだ。止められない衝動というものがあるとかなんとか。

というわけで emscripten です。

解説

ドメイン層

C++ でモデリング。今回は todo アプリを作ることにしました。

クラスとして todo という概念をモデリングしたあと、それを JavaScript から扱えるように binding を書いてやります。かんたんかんたん。 move semantics は意味があるのかどうかまだよくわらかないです…。

emscripten で JavaScript ファイル生成

↓に書いてあります。手元の環境は Mac OS X なので /opt 以下におきました。

うかつにパス通しちゃうと普段の node 環境つかえなくて焦ります。というわけで build するための sh script を書いておくと楽です。

最適化がどれだけ意味があるのか…。

emscripten が生成するファイルは ES Modules や Node.js で使われている CommonJS などというものは一切考慮しません。ブラウザーで読み込むと Modules というトップに変数を定義してその中に諸々を定義してくれます。えっ、まじで ?

html から読み込み、使用

script 要素で読み込むだけで準備完了です。トップに Modules という空間が定義されているのでそこから使いたいクラスや関数を呼び出します。今回はクラスしか定義していないので new でインスタンスを作って操作、破棄してやります。

const newTodo = new Modules.Todo('たすく')
newTodo.toggle()
newTodo.delete()    // !

えっ、破棄 ? delete ?

そうです。 emscripten の仕組み上 ArrayBuffer 上にインスタンスが作成されるので、明示的なインスタンスの破棄が必要になります。もう嫌な予感しかしませんね !!

UI を React Redux で組んでみる

C++ から UI を操作することは難しいため、 UI についてはその他のフレームワークを使ったほうがよいようです。というわけで今回は React Redux を選択しています。

簡単なので reducer の中でもろもろの操作を定義しています。

state の初期状態の定義や todo を追加する際の reducer で Modules.Todonew していますね。 todo を削除するところできっちり delete を呼び出しています。

普段のサンプルとちょっと違う感じがしますが、これは ducks という reducer の書き方の提案をもとに書いています。

React コンポーネントの定義については凝ったことはしていません。

感想

そんなにつまづくこともなくサンプルを作成できたので実はイケるんじゃ、と思わせつつも、次の点からロマン技です。

  • module の仕組みがない
  • 明示的にリソース管理をする必要がある

上記さえ解消されれば、型と速度を手に入れるための選択肢としては悪くないんじゃないかと感じました。

明日は @shinout さんの flow のハナシです。