Sider Blog

コードレビュー自動化サービス「Sider」を運営するSideCI株式会社のコーポレートブログです。



Rebuild.fmの宮川氏がRubyまつもと氏に聞いた、Ruby開発の10の論点

当ブログですでにお伝えしたように、Ruby誕生25周年を記念して、2018年2月24日に東京・品川で「Ruby25」というイベントが開かれた。イベントではRubyの生みの親であるまつもとゆきひろ氏のほか、RubyやRuby on Rails開発の第一人者らが集まって現在のRubyの現状について講演を行った。

イベントの最後のセッションとして「Rubyの未来〜Matz & Miyagawa 未来を語る特別対談」が行われた。エンジニア向け人気ポッドキャスト「Rebuild.fm」を運営していることで知られる在米日本人エンジニアの宮川達彦氏(米FastlyのPrincipal Software Architect)が、まつもと氏に次々と質問を投げかけるスタイルの対談だ。

ここでは、まつもと氏の回答から浮かび上がるRuby開発にまつわる10の論点をお伝えしたい。

f:id:sideci:20180224165622j:plain Ruby生みの親のまつもとゆきひろ氏(左)と、Rebuild.fmで知られる宮川達彦氏(右)

Rubyの後継者問題は「Matz_bot」で解決!?

今回のRuby25イベントでは、まつもと氏へのサプライズとして実の娘2人から父まつもとゆきひろへ花束を贈るというシーンがあった。その光景が、まるで「Rubyから引退したように見えた」ことから「実際のところ後継者問題はどう考えていますか?」と宮川氏はジョークを交えて質問した。

まつもと:(Ruby開発リーダーの)後継者はボット、AIに任せようという意見があって進行中です(笑)。今のうちからデータを集めとかないと、という話をしています。

宮川:技術的には可能な気もしますけど、どうなんでしょうか。まつもとさんの好みとか意見を反映したボットというものですね。

まつもと:たぶん2分の1の確率で「名前が気に入らない」というと思うんですけど。名前がダメ、ちょっと考え直してっていうね(笑)

Ruby開発における機能改善や追加提案では、提案者が実際のユースケースや良いベンチマークデータを示したとしても、メソッド名がRubyの世界の統一感にそぐわないと、そこで機能追加が止まるということがときどき起こる。Rubyでは「名前重要」というのが文化として定着していて、それを門番をしているのが他ならぬまつもと氏。まつもと氏が、ちょっとその名前は違うんだよなと言うと、しっくりと来る名前が考案されるまで機能追加パッチがペンディングになることがあるのだ。

まつもと:近い未来に私が事故とかに遭うとまずいんだけど、引退するときまでに今からデータとを集めておくと間に合う可能性が結構あるかもしれませんね。

宮川氏はここで「BDFLモデル」に言及した。オープンソース・プロジェクトにおけるガバナンスや意思決定の組織論として良く指摘されるのが「優しい終身の独裁者:Benevolent Dictator For Life」(Wikipediaの解説)のモデルだ。開発コミュニティーで意見が割れた際などに最終的な意思決定を行う人物として、そのプロジェクトの創設者が終身的にプロジェクトの中心に居続ける開発モデルのことだ。Ruby開発は多くのコア開発メンバーがいるが、最終的にRubyの方向性を決めるのはまつもと氏だ。

まつもと:ソフトウェアプロダクトとしてRubyを見たときに、そのデザインに対して少数の人が意見を出して方向性を決める。そういう「プロダクト・オーナー」とか「プロダクト・マネージャー」のようなヒトが1人のほうがいいと思うんですよ。Rubyの場合は私になっている。いい判断をしたら褒められるし、悪い判断をしたら私がけなされる。で、誰かがいい提案をして私が「うん」というと褒められる、という非常に素晴らしい仕組みになってるわけです(笑)

(会場笑)

Linuxのサブシステムのような開発の分業は可能か?

BDFLモデルに続いて、宮川氏はLinuxカーネル開発のようにサブシステムによるデリゲート(移譲)はRubyでは可能か、直近のRubyコア開発ではどうなっているのかと質問を投げかけた。

まつもと:Rubyの場合はサブシステムはうまくいかないですね。Linuxみたいにファイルシステムはサブシステムで、そこから先はあまり本体に関係ありませんとか、スケジューラはここだけ変えると性能特性が改善しますとか、そういう感じではないんです。

Rubyでも文字列周りや正規表現は誰がやりますとか、バーチャルマシンは誰がやりますとか、緩やかなチーム分けみたいなのはあります。そこの技術判断について良い悪いということは私はあまり言わないです。彼らが自分で判断できると思っていますので。

でも、言語的にどんなメソッド追加するかとか、新しい機能をどうするか、名前をどうするかということについては、やっぱり最終的に優しい独裁者である私の判断が必要になってくるんですよね。25年も開発をやっていると一貫性といっても「昔はまつもとこう言ってたじゃん」という風に、必ずしも一貫していないこともあります(笑)。ただ、そうは言っても原則的にRubyというのは1人の人間のポリシーに沿って作った、という感じにはなってると思うんですよね。

Ruby3は連続開発モデルを採用してブランチは切らない

続いて宮川氏は次期メジャーバージョンアップ版となるRuby3について質問。「いちばん重要だと言ってたのは、Ruby3のブランチを切って、Ruby2と別に開発するのではないということですよね?」と水を向けた。

まつもと:はい、連続的な開発でやろうと思っています。Ruby2のときには、いくつかの機能はRuby1.9に入っていなくて、Ruby2.0で初めて入れたという「ブランチモデル」でバージョンアップしました。今回はメインラインで開発を進めていき、ある一定のしきい値を超えたときに、これだったらバージョン3と言っていいと主に私が思ったときにRuby3.0ということにしようと思っています。

Ruby1.8からRuby1.9のときに非連続なバージョンアップをしてしまって、その結果、コミュニティーが分断したんですよ。古いバージョンを使い続けている人は「移行コストを払えないから」ということなんでしょうけどね。新しいバージョンでは、こんな素晴らしい機能があるとか、性能が改善したのに、そういう利益を享受できないユーザーが出てくる。

Ruby1.8のユーザーは、5年とか、ひどいと10年ぐらい遅れて「もう仕方ないな」と重い腰を上げてバージョンアップするようなケースがありました。それだと、いろんな意味で力が分散してしまってもったいないなと思うんですよ。これはRubyだけじゃなくて、ほかの言語でも起きていることなので、ありがちな失敗だと思うんですよね。今回はほかのコミュニティーの反省も踏まえてラベルモデル(継続的に進化していくモデル)がいいかなって思っています。Linuxもバージョン3以降はラベルなんですよね。「そろそろいい頃合いだから3と呼ぼう」というモデル。それを参考にして、Rubyでもラベルモデルを採用しようということです。

f:id:sideci:20180224165735j:plain

Ruby3では後方互換性を壊さない

連続的なバージョンアップということは、「非互換の変更は入れないということですか?」と宮川氏は聞いた。

まつもと:はい、原則的に非互換の変更はやりません。過去のうっかりしたバグがあって、これは本当はこうするつもりだったけど間違いなんだよというものは直すと思います。これまでにもバージョン2.3から2.5の間に、そうした修正はしています。もちろん直すとしても変更の警告を出して、その次のバージョンから変えるようにしたいなと思います。

25年も開発をやってると全部の技術的判断が正しかったということはありません。「ここは直したいな」というところがないって言ったら嘘になります。でも過去に気軽に後方互換性を破壊して前に進んできた経験から正直に言うと、「気に入らないけど、これはもう仕方がない」と諦める感じになるかなと思います。

どんなに些細な変更、あるいはバグの修正であっても、これだけRubyユーザーが増えると、世界のどこかにその機能を使っているユーザーがいるんですよ。すると「オレのソフトウェアが動かなくなったぞ、どうしてくれる」と言われたりしてね(笑)。程度によってはrevert(修正を元に戻すこと)しなきゃいけないし、場合によっては互換性を壊してごめんなさい、という謝るだけのケースも出てくると思います。

Rubyは最近すごく保守的な判断をしています。過去の互換性を気にしたりね。一方、Ruby on Railsはものすごくドラスティックに後方互換性を壊すんですよね。これが同じRubyコミュニティーかっていうぐらい違います(笑) これにはたぶん理由があって、われわれはプログラミング言語という「下のレイヤー」なので変化することの影響が大きいんですね。コンパイラ技術も基礎的なものが開発されたのは1970年代のものですしね。一方で、ウェブは進化が速くて、新しい技術や概念、気をつけなきゃいけないことっていうのがどんどん出てきます。だからRailsの(互換性を壊しながら進化するという)判断は、それはそれですごいです。われわれ(Ruby言語の開発者)は互換性を保ったまま機能追加や性能改善をしていこうという、ある意味、より技術的チャンレンジをしていこうということですね。

JITは性能特性を見ながらデフォルト動作を決める

続いて宮川氏からの質問は開発版のRuby2.6にも取り入れられたJITの話や、今後Ruby3に入る型推論の話に。

まつもと:(Ruby2.6でも取り入れられた)MJIT*1は、機能ではなく処理系の実装なのでRubyとしての動きはそのままで、実行速度が速くなるというものです。あるタイミングからJITを有効にするかもしれないし、まだ分かりません。Rubyだとスクリプトみたいに頻繁に起動する使われ方もするんですけど、JITがある処理系って立ち上げが遅くなるんですよね。起動した直後は遅くてコンパイルが進むとだんだん速くなる。サーバーみたいに長寿命のプロセスだと、トータルではすごく速い。JRubyなんかは同じRubyでもそういう特性を持っているんですけど、それがすべてのケースで望ましいとは限らないので、どの時点でJITを有効にするのか、そもそも明示的に指定しないと使えないようにするかなど、そうしたことはまだ性能特性を見ながら決めていかないといけないかなって思っています。もうちょっと様子を見たいですね。JITは、より多くのメモリを消費するので、それがボトルネックになるようなケースでもうれしくないかなと思います。

型推論でIDEでの補完や型チェックなどは可能になっていく

f:id:sideci:20180224165800j:plain 宮川:Ruby3には「Steep」*2という型推論が入るという話ですが、えーと、まつもとさん的には、どうしても型を書きたくないと?

まつもと:はい(笑) Rubyコミュニティーには、プロトタイプ的に型を書くのはいいんじゃないという人が多くてですね、その中で私が1人だけ「絶対書きたくないから!」と言って、みんなから白い目で見られているんですけどね。

Rubyって型を書かなくてもプログラムは動くんですよね。で、その動くプログラムにまた型を書くっていうのはDRYじゃない感じがするんです。書かなくていいのに、「書くといいよ」と言われると、「えーっ」って(笑) コードの字面上で型を書くのは嫌だな。

型推論であるとか実行時に型情報を集めてきて、このクラスのこのメソッドはこの型を引数で取ってこの型を返しますっていう情報を持っていて、それを使って将来的には型チェックをようなものとか、IDEの補完機能のようなものをRubyに入れていくことはできると思っています。

宮川:Rubyも好きで良く書くんですけど、例えばGoとかで書いたとき、型を指定しておいたときの自分の中の安全感は、それでそれで気持ちいいんですよね。Rubyの気持ちよさと違う種類の気持ちよさかもしれませんけど。

まつもと:そうですね、情報が多いとそれだけできることは多いです。JavaをEclipseで開発してるとリファクタリングをツールがサポートしてくれて便利。grepとEmacsのテキスト置換でもなんとかできちゃうんですけど……(笑)。でも冷静に考えると、クラス名を変えるよといったら、ごっそり変えて型情報も一気に変換してくれたほうがいいわけですよね。そういうことができるために、別ファイルとして型情報があれば、精度が高いプログラムを書くことや読むことの支援ができるんじゃないかなと思います。GoとかJavaの良さのようなものは、100%じゃないにしても、RubyがRubyのままでも提供できるんじゃないかなと思って鋭意開発中ですね。

Rubyでは今後マジックコメント(プラグマ)は増やさない

非互換の実装は入れないということだが、新しい文法や機能はどうか? 宮川氏が切り込む。

宮川:新しいシンタックスを入れようと思ったら、いまのRubyでシンタックスエラーになる構文じゃないと入れられないですよね。

まつもと:そうなんですよ。Rubyって、「これ本当に(文法チェック)通るの?」みたいなのが通るんですよね。パーザーを書いた本人が言うのもひどい話ですけど、シンタックスエラーの範囲が狭くて、なかなか新しい文法が足しづらいというのがありますね。

宮川:パーザーの挙動を変えるための、オプトインのプラグマみたいなものを入れないんですか?

まつもと:Rubyで挙動を変えるのに一番近いのは「マジックコメント」というのがあって、いちばん影響が大きいのは「frozen_string_literal」というのがあって、リテラルの文字列が変更不可、イミュータブルになるんですね。Ruby3.0にするときに、これをデフォルトにするかどうか。これは私自身、聞かれるたびに答えが違うという感じですね(笑)こういう大きな変更は良くないぞ、いやそうはいっても3.0はいい機会だから変えようか、と思ったりね。Ruby3に間に合わないと思うんですけど、パッケージとかネームスペースについては真剣に考えないといけないなとも思っていますね。

人間を支援するツールに徹底する

宮川:人間を支援するコンピューターという方向にプログラミングも進化していくべきだと思いますか?

まつもと:基本的にはプログラミング言語なんていうのは、人間がコンピューター並みの処理能力をもっていれば不要なわけです。いきなりバイナリをしゃべればいいわけですから。でも人間には残念ながらそんな能力はありません。仕方がないので妥協点としてプログラミング言語を使わざるを得ないんですね。そこでどのくらい妥協するかというのがあって、まあRubyの場合は思い切り人間側に寄って、人間を楽にするように、コストを機械に払わせようという思想なんですね。これからさらにコンピューターのパフォーマンスがあがると、より無駄遣いしていいリソースが増えるので、開発を支援するほうにそのリソースを使いたいっていうのがRubyの思想ですね。

宮川:人間が考えてるものをダンプするツールとしてのRubyみたいなものですか。

まつもと:そうですね、できるだけ「what」を記述することで済ませたいですよね。何がしたい、ということだけ書く。そうはいってもコンピューターは馬鹿だから「How」を書くんだけど、そこを最小限にするとき、Rubyを使ってコンピューターに教えてやりたいってことです。

Python人気で歯がゆい思いをしてる?

宮川:新しい教育の現場とかだと最近はPythonが強いと思うんですよね。プログラミング言語として癖がないとか、機械学習のような実践的なところで強くなってるのかなって思うんですけど、そのへんは歯がゆいですか?

まつもと:例えば10年ほど前にRubyがウェブ開発の前線でRails人気だったころ、Pythonの人たちは科学計算ライブラリで頑張っていたり、教育分野に向けて伸ばすことに対して継続的に努力していて、それが実を結んだってことはあると思うんですよね。Rubyでも同じようなルートをたどっていかないといけないかなっていうのは思っていますけど。

宮川:PythonとRubyが180度、全く違う言語とはぼくは思わないんですけど。

まつもと:そうですね、60度くらいですね。

(会場笑)

今後まつもと氏がRuby以外の作品を作る予定は?

宮川:Rubyというプログラミング言語を作って、すでに一番有名な作品なわけですけど、この後、Rubyじゃない何か作ってみようというのはないんですか?

まつもと:サイドプロジェクトみたいなものをやるっていうのは考えていないわけではなくて、何年か前には「Streem」*3という名前のプログラミング言語を作ったりしました。Rubyと違うタイプの規模の小さなプログラミング言語を作って。まだおもちゃレベルなんですけど、これはこれで楽しいので、たまに思い出したように、Streemのアイデアを試すみたいなのは楽しいので、そういうのは少しずつはやると思うんですね。やりたいっていうことで言うと、昔からデータベースみたいなものを作りたいと思ってますね。Redisなんかすごく私が作りたいものに近い。結局、下のレイヤーが好きなんですね。でも最初の一歩ってだいぶハードルが高くて。

Rubyはライフワークなので、もうRubyを引退しますっていうことはないです。Rubyというのは私が生きている間は面倒をみたいと思っていますし、私が引退するまでに開発を継続できるような仕組みができるといいなっていうぐらいには思っていますね。

(SideCI特別取材班)