まつもとゆきひろさんインタビュー
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
と書くと、e1
や e2
のプログラムのことをストリームと言っています。このストリームの各要素ごとの処理をタスクと呼んでいます。タスクは、データを受け取って生成され、処理を行い、そして加工したデータを次のストリームに渡して終了していきます。これらのタスクが、システムのコア数分だけ、同時に実行することになります。
笹田 タスクが無限ループみたいなことをすると、そのコアは占有されちゃうんですか?
まつもと されてしまう。なので、書かないようにしないといけない。ただ、while
のような構文はないので、ちょっとやりづらい。関数定義ができるので、再帰してしまえば、ループは作れるんだけど。
笹田 並行処理のことを考えると、データは immutable なんでしょうか。
まつもと 基本的にそうです。もちろん、実装レベルでは書き換えているけど、Streem レベルでは immutable です。
笹田 構造体みたいなものは使える?
まつもと タグ付きの配列、というものがあります。Hash の代わりに使えます。
笹田 それも immutable?
まつもと そう。その代わりに、Hash がない。mutable じゃないと作れないと意味ないかなって。
笹田 いや、使っている側からすれば、別に変わらないんじゃないですか? いわゆるマップ(辞書)データ構造が使えるなら、性能がどうか、という点以外で、あまり関係ないと思うけど。
まつもと そもそも、マップのようなデータ構造は、immutable なプログラミングにはあわないと思うという直感があって、どこまでできるか確かめてみたい。
笹田 使う側からしたら、そのタグ付き配列と、マップは変わらないと思うけどな。
Streem の実装
笹田 そして、実装は、このあたりのノンブロッキング I/O が大変だった、という感じでしょうか。
まつもと そうだね、epoll
を使って書いたり。あと、すべて並列実行されるので、全体をスレッドセーフなプログラムにしないといけないんだけど、それが大変でした。コンカレンシーとかの経験があまりない古いプログラマなので。
笹田 こういうところで Rust を使うといいんですかね。
まつもと そうかもね。
Ruby の話
笹田 Ruby にどう繋がりますかね。それとも、関係ない?
まつもと 正直、あんまり関係ないよね。並行・並列プログラミングに関する経験値は上がったかな、と。それから、ちょっと前に考えていたのが、この実行モデルを Ruby 3 の並行モデルにどうかな、と思ったんだけど、互換性を考えると、実は別の案じゃないとまずいかな、と思い始めている。
笹田 これくらいのモデルなら、Ruby のライブラリとして実装してもできると思うけど。もちろん、これだけを使うように閉じることはできないけど。
まつもと 去年の時点で考えていたのは、VM を複数もっておいて、プログラム終了時にそれまでに設定したパイプラインネットワークをデータを流す処理を行うふたつめのVMが起動する、というものでした。ただ、既存のプログラムからの移行ということを考えると、違う形のコンカレンシーモデルを提供したほうがいいかな、と思い始めています。
笹田 他の方、例えば昨日インタビューした辻本さんはパターンマッチの提案して下さるそうです。
まつもと パターンマッチ入れたいんだけどね。既存の文法との共存が心配。
笹田 ぜひ、東京 Ruby 会議 11 で議論してください。
まつもと はい。
笹田 発表、とても楽しみにしています。今日はお忙しいところありがとうございました。