Ruby
rubykaigi
typings
rubykaigi2018
GradualTyping

ご意見、ご指摘、または議論等ありましたらコメント欄によろしくお願い致します。

前置き

RubyKaigi2018 の発表で型の導入の検討についての話がいくつかあったものの、 Matz 自身は型アノテーションに否定的であるという発言をしているとのことを受けて、自分の意見の表明として書いている。

筆者は Ruby に育てられて Ruby は好きであるが、業務経験は主に JavaScript(TypeScript) や Python(Type Hinting) が多く、漸進的型付けによるコードの健全化を経験した上で、型付きの方が好きであるという立場である。

なお、当時のハッシュタグに多くの参加者の意見が書かれているので、参考としてほしい。Replay for RubyKaigi に感謝。

Ruby の選定について

現代の Web 開発において Ruby を選定するケースは主に Rails だと考えている。

Rails を選定する理由は様々だと思うが、 Rails の代替となりうるフレームワークとして有力なものは静的/漸進的型付き言語にはなく、現実問題として Rails を採用しているプロダクトは多く存在する。

Single Page Application やネイティブアプリのようなフロントエンド比重が高く、サーバサイドは API のみというプロダクトであれば Ruby/Rails 以外を選定するというのは現実的であるが、そうでない場合に Rails になるケースはまだ多く存在するだろう(比較対象が WordPress を使うか PHP を使うか、程度だろう)。

Ruby で型が欲しいシーンと欲しくないシーン

Ruby は柔軟な言語仕様を持ち、(ちゃんとやれば)オブジェクト指向がやりやすい言語であると感じる。

しかし力量差があるチームでコードを書く場合、 (Ruby に限らず)動的型付けの場合はオブジェクト指向の秩序が乱れる恐れがある。

そのような秩序の乱れを防ぐ目的として、力量差が往々にして存在する現場では Java 等が採用され、Interface や Abstract Class によって堅くしているように見える。

Ruby でもこのような規則を用いて開発を行いたい場合に型が欲しいこともあり、特に秩序が乱れつつある/既に乱れてしまった大規模プロジェクト(主に Rails)で特に型が求められているように感じる。

一方、個人で開発している場合は本人が不要だと感じれば不要であるし、過去の自分のコードが読みにくいとは言われつつも、自分のルールに即していれば壊滅的にはならない場合もある。

(秩序が壊滅するのは、チーム内で共通認識が取れていない謎コード等が発端になると感じる)

また、熟練したメンバーのみで開発を行っている場合、言語による縛りがなくとも設計を保つことができるケースでは型は不要であると考える。(私は Ruby において熟練しているとは言えない立場なので想像を多分に含む)

現在の Ruby はこれらのそれぞれの用途で仕様されているため、型をコア機能としてしまうのが良くないことは分かる。

しかしオプショナルなものとして型があるのであれば、必要に応じて選択でき、 Ruby の従来の柔軟性を失わないのではないかと考える。

以下、型が欲しいシーンとして「秩序が危ぶまれているので型によって健全化したい」という意見を前提に意見を述べる。

なぜ型に期待するのか

秩序が欲しいだけならば型に限らないのだが、それでも型に期待する理由としては主に以下があると考える。

  • JavaScript や Python での漸進的型付けによる成功体験
  • Ruby に型を入れる、という Matz の発言による期待値の高まり
  • JIT の性能向上の期待

Matz が初めから「型は入れない」と言っていたら期待値は変わっていたかもしれないし、型が欲しい人は早々に見切りをつけていたかもしれない。

なぜ型アノテーションを標準化してほしいか

例えば Python では型定義が pep484 によって標準機能に含まれているため、サードパーティ製のどの静的型解析ライブラリを仕様する場合でも、大方問題なく使い回すことができる。

しかし Ruby のサードパーティ製の静的型解析ライブラリは現状いくつかあるが、それぞれ独自の型定義方法を持っているため、そのライブラリにロックインすることになってしまう。

Ruby の文法に組み込まれるか、デファクトとなるライブラリが確立しないことには Rails 等の大きなライブラリでは型を付け始めにくいし、大手が使い始めないとデファクトになりにくい、という悪循環に陥っていると感じる。

この状況の打破としても、 Ruby 公式で型アノテーション記法を定めることは大きな意義があると考えている。

(言語記法に組み込まないのなら組み込まないで、型情報コメントの記法を公式に定めてしまう程度でも全然良いとは思う。)

「型が欲しいなら Ruby じゃない言語使えばいいじゃん」問題

このような意見はごもっともで、自分も新規でプロダクトを作るときに、型が欲しい人が積極的に Ruby を採用する理由はないと考えている。

問題は新規プロダクトではなく、すでに数年が経っているプロダクトの方で、そこに秩序を持ち込むための手段として型を望んでいるところが大きいと感じる。

特に JavaScript に徐々に型を導入して秩序を持ち込めた成功体験があればこそ、漸進的型付けに対して希望を持ちがちかもしれない。

逆に、型がなくてもやっていけるという確信や信頼を持てるチームであれば全く問題ないのだが……

型が欲しいときにできること

型がないプロダクトでこれ以上やっていきたくない、という段階で型が欲しいときの選択肢は以下だと考える。

  • soutaro/steep 等のサードパーティ製の型定義を各種ライブラリにコントリビュートしていく
  • プロダクトを型付き言語で作り直す
  • プロジェクトを離れる

1 つ目について、自分たちが書く箇所に型があるよりも、ライブラリ側に型がある方が恩恵が大きいと感じる。逆に言うと、ライブラリで型が提供されない場合、呼び出し箇所全てに型定義が必要になる。

2 つ目について、これはかなり政治的な問題が大きい。パフォーマンスが出ないとか、もうメンテが無理という状況でないと積極的にフルスクラッチするのは難しい。まあエンジニアがこぞって「もうメンテ無理、辞める!」とでもなれば話は別なのだが、そうなっている時点でかなりプロジェクトの治安が怪しい……。

ということで上記 2 つは難しく、 Rails プロジェクトを離れることが有力になってしまう……

これは Ruby としても利用者が減ってあまりよろしくないと思うので、 Matz には考え直して欲しいところである。

Rails が悪い/終わったわけではない

「Rails は終わった」という話をする人もいるが、全く終わっていないと考える。

確かに現状 Rails が大きくなってしまいつらい状況になっているケースを見聞きすることはあるが、悪目立ちするもので、健全に Rails で運営し続けているプロダクトもあるだろう。

あるいは、Single Page Application の文脈で終わったと言っている場合もあるが、世の中の全てが SPA なわけではないし、従来のドキュメントベースの Web プロダクトを開発する上ではやはり Rails はパワフルである。

秩序が乱れている原因は開発者が Rails をコントロールしきれていないところにあるように感じている。

(私は Rails をコントロールできる自信がないので、 Rails で今から作るなら型が欲しいか、別の選定をするだろう、という意見である。)

型がない Ruby での活路

上記の話は Web アプリケーションという文脈が主になっているが、実際問題として Web 開発の文化圏では全身的型付けが導入されてきていたり、 Go の人気もあり、型が欲しいという声が大きいところは、現在の Ruby には少々不利であるように見える。

しかし、ミドルウェアの組み込み言語としては、有名な Lua は動的型付け言語であるし、そのレイヤーで型が欲しいという声が強いという感じはあまりない。

個人的には Web 開発では型付き言語を使いたく、また Matz が力を入れていることもあり、新たな活路としての mruby への期待は大きい。

おわりに

Ruby と型についてはいろいろ思うところはあるが、 Ruby は好きであるので、活躍の場が減らないように、現場に受け入れられやすくなるように、進化していって欲しいと思いこの記事を書いた。

謝辞

RubyKaigi 2018 には所属している株式会社リブセンスの支援の元、業務の一環として参加することができました。会社に感謝するとともに、このような文化を持つ株式会社リブセンスをよろしくお願いします。


原著: Eutech Blog