東京 Ruby 会議 11 直前特集号

10:10 Invited Speaker

Streem

発表概要は、事前インタビューをご覧下さい。

必要となる知識

まつもとゆきひろ
日経Linuxライター


5/16 Skypeにて伺いました(話し手:まつもとさん、聞き手:笹田)。

笹田 今回、タイトル「Streem」だけ頂いていて、概要を頂いていないのですが、どんな話になるでしょうか。

まつもと Streem という言語を作っているので、その紹介をしようと思います。言語仕様の話と、それをどう実装したか、という話になるかと思います。やや言語の方が多いかも。

Streem の言語仕様

笹田 言語仕様って固まりましたか?

まつもと 言語レベルでは、多分固まってきたと思うんだけど、ライブラリが足りていない。言語の使われ方ってライブラリで決まったりするので、そういう意味ではまだまだだと思います。

笹田 なんとなく、パイプでつなげていく、ということしかわかっていないのですが。

まつもと はい、それであってます。

笹田 どれくらい書きやすいものになるでしょうか。

まつもと 得意不得意はあるよね。今までループで回していたようなものは書きやすくなるんだけど、複数データを、複数のループで、いろんなデータを切った貼ったするのは得意ではなさそう。

笹田 まだ、まとまった資料はないですよね?

まつもと 『日経 Linux』の連載「作りながら学ぶプログラミング言語」しかないですね。どれくらい読者がいるんだろう。まとめて本とか出せるといいんだけどね。

笹田 そういう計画はあるんですか?

まつもと mruby の連載は電子書籍になったんだけど、この連載については何も聞いてません。元々 Streem のための連載じゃないので、まとまりが悪いんだよね。

笹田 最近の新しい言語、例えば Elixir や Rust とか、ウェブサイトからライブラリから、周辺をすごい整備されていると思うのですが、Streem は、そういう計画はありますか?

まつもと ありません。Ruby の時もやらなかったしね。

笹田 誰かやってくれると良い、と。

まつもと やってくれると良いよね。

笹田 得意不得意ってありそうですか? 例えば、ウェブアプリケーション開発は、とか。

まつもと 多分、ウェブアプリケーション開発とかよりも、CSV からデータを読み込んで、統計処理とかフィルタリングとか、ログデータからフィルタリングしたりとか、そういのが楽になるんじゃないのかな。まさに、シェルスクリプトのような。もちろん、ウェブアプリケーションも、リクエストを加工してレスポンスを作る、ということでできると思うんだけど。多分そんなに向いていないんじゃないかな。

笹田 Elixir は、まさにそういう概念で、データをストリーム処理していく、という概念の上で作られていて、Phoenix フレームワークとかも出てきて、ちゃんと出来るとは思うけど。

まつもと できないことはないと思うよ。

笹田 モジュール化とかは?

まつもと まだ、そういう機能はないです。

笹田 では、本当に シェルスクリプトで、流すデータがバイトストリームではなく、文字列や配列などに代わったもの、という感じでしょうか。

まつもと そう。

笹田 並列処理は?

まつもと パイプラインがそれぞれ並列に動きます。コアの数だけ OS のスレッドを作って、その上で動かします。なので、普通にパイプライン書くと、マルチコアを活用できる。

笹田 用語の整理をさせて下さい。今、GitHub のページのサンプルを見ているのですが、この seq(100) … の例だとどういう話になるんでしょうか。

seq(100) | {x ->
  if x % 15 == 0 {
    "FizzBuzz"
  }
  else if x % 3 == 0 {
    "Fizz"
  }
  else if x % 5 == 0 {
    "Buzz"
  }
  else {
    x
  }
} | stdout

まつもと e1 | e2 と書くと、e1e2 のプログラムのことをストリームと言っています。このストリームの各要素ごとの処理をタスクと呼んでいます。タスクは、データを受け取って生成され、処理を行い、そして加工したデータを次のストリームに渡して終了していきます。これらのタスクが、システムのコア数分だけ、同時に実行することになります。

笹田 タスクが無限ループみたいなことをすると、そのコアは占有されちゃうんですか?

まつもと されてしまう。なので、書かないようにしないといけない。ただ、while のような構文はないので、ちょっとやりづらい。関数定義ができるので、再帰してしまえば、ループは作れるんだけど。

笹田 並行処理のことを考えると、データは immutable なんでしょうか。

まつもと 基本的にそうです。もちろん、実装レベルでは書き換えているけど、Streem レベルでは immutable です。

笹田 構造体みたいなものは使える?

まつもと タグ付きの配列、というものがあります。Hash の代わりに使えます。

笹田 それも immutable?

まつもと そう。その代わりに、Hash がない。mutable じゃないと作れないと意味ないかなって。

笹田 いや、使っている側からすれば、別に変わらないんじゃないですか? いわゆるマップ(辞書)データ構造が使えるなら、性能がどうか、という点以外で、あまり関係ないと思うけど。

まつもと そもそも、マップのようなデータ構造は、immutable なプログラミングにはあわないと思うという直感があって、どこまでできるか確かめてみたい。

笹田 使う側からしたら、そのタグ付き配列と、マップは変わらないと思うけどな。

Streem の実装

笹田 そして、実装は、このあたりのノンブロッキング I/O が大変だった、という感じでしょうか。

まつもと そうだね、epoll を使って書いたり。あと、すべて並列実行されるので、全体をスレッドセーフなプログラムにしないといけないんだけど、それが大変でした。コンカレンシーとかの経験があまりない古いプログラマなので。

笹田 こういうところで Rust を使うといいんですかね。

まつもと そうかもね。

Ruby の話

笹田 Ruby にどう繋がりますかね。それとも、関係ない?

まつもと 正直、あんまり関係ないよね。並行・並列プログラミングに関する経験値は上がったかな、と。それから、ちょっと前に考えていたのが、この実行モデルを Ruby 3 の並行モデルにどうかな、と思ったんだけど、互換性を考えると、実は別の案じゃないとまずいかな、と思い始めている。

笹田 これくらいのモデルなら、Ruby のライブラリとして実装してもできると思うけど。もちろん、これだけを使うように閉じることはできないけど。

まつもと 去年の時点で考えていたのは、VM を複数もっておいて、プログラム終了時にそれまでに設定したパイプラインネットワークをデータを流す処理を行うふたつめのVMが起動する、というものでした。ただ、既存のプログラムからの移行ということを考えると、違う形のコンカレンシーモデルを提供したほうがいいかな、と思い始めています。

笹田 他の方、例えば昨日インタビューした辻本さんはパターンマッチの提案して下さるそうです。

まつもと パターンマッチ入れたいんだけどね。既存の文法との共存が心配。

笹田 ぜひ、東京 Ruby 会議 11 で議論してください。

まつもと はい。

笹田 発表、とても楽しみにしています。今日はお忙しいところありがとうございました。