RubyKaigi 2014 レポート

まつもとゆきひろさん、Ruby 3に向けて組み込んでみたいアイデアを提案 ~ RubyKaigi 2014 2日目 基調講演

2014年9月18日~20日の3日間、タワーホール船堀にてRubyKaigi 2014が開催されました。基調講演をそれぞれレポートします。

画像

2日目の基調講演は、まつもとゆきひろさんです。まつもとさんは、過去に開催されたRubyConfでRubyに取り込んでみたいアイデアを提案してきました。しかし、最近のカンファレンスではRubyの未来についてあまり言及していませんでした。そこで今年は「Comming Soon...」というタイトルで、Ruby 3のアイデアを話しました。

今まで提案してきたアイデアを振り返る

2001年

まつもとさんは2001年のRubyConfでRubyのVirtual Machineを作りたいというアイデアを話しました。当時、まつもとさんはVirtual Machineのプロトタイプを作っていましたが、互換性を保ったまま動かせるように作るのが大変だったので、途中で挫折してしまったそうです。

画像

その後に笹田さんが別の方法でRubyのVirtual Machine(YARV)を作り、これはRuby 1.9に組み込まれました。Ruby 1.9は2007年にリリースされたので、2001年にまつもとさんが語られたアイデアは6年後に現実化したことになります。

2002年

2002年のRubyConfでは「他言語化(M17N⁠⁠ネイティブスレッド」⁠世代別GC」について話しました。M17NとネイティブスレッドはRuby 1.9に、世代別GCはRuby 2.1に組み込まれました。

2003年

2003年のRubyConfにも基調講演として参加し、前年と比べてとても多くの新しいアイデアを話しました。

  • ローカル変数のスコープのルール変更
  • 多重代入のルールの明確化
  • ローカルメソッドの可視性変更
  • キーワード引数
  • メソッドコンビネーション
  • Selector Namespace
  • Optional Static Type

この年に語られた7つのアイデアの中で現実化されたアイデアは「多重代入のルールの明確化」⁠キーワード引数」⁠メソッドコンビネーション」⁠Selector Namespace」の4つです。⁠ローカル変数のスコープのルール変更」「ローカルメソッドの可視性の変更」については互換性を破壊せずに組み込むことができなさそうだったため、諦めてしまったそうです。また、⁠Optional Static Type」については提案してみたものの、現実化される気配がないようです。

2004年

2004年はRubyConfは欠席しましたので、未来について予想はしていませんでした。

2005年

2005年のRubyConfでは「ラムダ式(Stabby lambda⁠⁠Real multi-value」⁠Traits」について語られて、⁠ラムダ式(Stabby lambda⁠⁠」がRuby 1.9で組み込まれました。 発表当時はラムダ式の記号「->」に反対意見が多かったようですが、実際にRuby本体に組み込まれてからは好意的な意見が寄せられたそうです。

2006年から2009年まで

2006年から2009年までのRubyConfでは新しいアイデアを語らず、⁠自転車置き場の議論」という逸話や、Ruby 1.9リリースなどについて話しました。

久々に新しいアイデアを語られることになったのは、RubyKaigi2009の基調講演になります。このときは次のアイデアを話しました。

  • 複素数リテラル
  • 有理数リテラル
  • True division
  • Bitmap marking
  • Symbol GC

「True division」「Bitmap marking」は現実化されていませんが、⁠複素数リテラル」「有理数リテラル」はRuby 2.1で、⁠Bitmap marking」はRuby 2.0で、⁠Symbol GC」はRuby 2.2で実装されました。

2010年

翌年である2010年のRubyConfでは次のアイデアを話しました。

  • Mix(Traitsの再考)
  • Module#prepend
  • Refinement
  • RiteVM

このうち「Module#prepend」「Refinement」はRuby 2.0で組み込まれました。また、組み込みなどの小規模なデバイスをターゲットとした処理系を目指していたRiteVMは、mrubyという名前に変えて2012年にリリースしました。4つのアイデアの内、3つは現実化されているということです。

2011年から2014年までのRubyConfでは新しいアイデアについては語られませんでした。

振り返ってわかったこと

振り返ってみると、2010年のカンファレンスまで、まつもとさんは多くのアイデアを提案してきました。しかし、2011年からのカンファレンスでは新しいアイデアを何も提案していません。最近のRubyはメモリについての改善が著しいので、Rubyは確実に成長していますが、新しいアイデアについて語らない時期が続くのは辛いことです。

「OSSコミュニティはまるでサメのようで、泳ぎ続けなければ死んでしまう」

そう考えたまつもとさんは、Rubyコミュニティに新しい燃料を投下するために、Ruby 3のアイデアを話しました。

Ruby 3のアイデア

まつもとさんは、Ruby 3へ向けて実装したいアイデアとして、次の3つを挙げました。

  • Concurrency
  • JIT
  • 静的型付け

このうち今回の講演で取り上げたのは静的型付けについてでした。

静的型付け

20世紀に生まれた言語は変数に型が必要ない言語が多いです。一方で、ScalaやTypeScript、Dartなど最近生まれた言語はスクリプト言語のような使い方をされながらも静的な型を持っています。

このことについて、まつもとさんは「悔しいからRubyに静的な型を導入してみようか」と思っていたところ、ruby-trunkのチケット#9999にて「次の文法で型を宣言するのはどうだろうか」と提案がありました。

def connect(r -> Stream, c -> Client) -> Fiber
  ...
end
画像

静的型付けのメリット

静的型付けはRuby以外の言語でも注目されています。では、静的型付けを導入することでどのようなメリットがあるのでしょうか。よく言われている静的型付けのメリットについて、まつもとさんは「パフォーマンス」⁠コンパイル時のチェック」⁠ドキュメンテーション」の3つを挙げました。

パフォーマンス

「Rubyは遅い」という意見がよくありますので、もしも静的な型システムを導入することでパフォーマンスが上がるのであれば、導入しておきたいです。しかし、JavaScript V8やLuaJITなどはRubyのような動的な型システムを持ちながらパフォーマンスが良い言語は存在します。

言語を実装している人の能力や、どれだけの資源を費やしたかがパフォーマンスに繋がるとまつもとさんは考えているそうですので、パフォーマンスのために静的な型が必要だとは言えないのではないかと述べていました。

コンパイル時のチェック

静的型付けを導入することで、コンパイル時にメソッドの引数の型を静的に解析できるようになります。引数の型や数がバグの原因となることはよくありますので、解析によってバグを早い段階に網羅的に検出できるようになるのは嬉しいことだと言います。

ただし、コンパイル時にバグを網羅的にチェックしてくれるようになったとしても、すべてのバグを見つけることはできません。静的な解析があるのでテストカバレッジが少なくてもいいということはありませんので、その点は注意しなければいけません。

ドキュメンテーション

Rubyの文化では、変数にわかりやすい名前をつけて「この変数は何をするのか」⁠どのクラスのオブジェクトを渡せばいいのか」を示すことがよくあります。この方法でもドキュメンテーションの効果はあります。しかし、変数の名前はコメントのようなものですので、変数名やコメントから得た情報と実際に渡さなければいけないオブジェクトに矛盾がある可能性もあります。

静的型付けが導入されていれば、型宣言と矛盾するコードを書いていたときにエラーとなるため、信頼性が高いドキュメントとして扱うことができるのではないかという考えがあるようです。

今のRubyが静的な型を持っていない理由

ここまで、まつもとさんは静的な型を持つメリットを取り上げました。では、なぜ今のRubyは静的な型を持っていないのでしょうか。

まつもとさんはRubyが静的な型を持っていない理由について、次の3つを挙げました。

  • ダックタイピングとの相性の悪さ
  • 使うかどうかを選択可能(Optional)にしなければいけない
  • DRYの哲学に反する

ダックタイピング

Rubyには「文字列のように振る舞うオブジェクトであれば、内部構造が文字列ではないとしても、文字列だと捉えて動くようにすべき」というダックタイピングという哲学があります。Rubyの多くのライブラリが既にこの哲学に乗っ取って作られているため、そこに突然静的型付けを導入してしまうと、混乱が生じるのではないかという不安があります。

選択可能(Optional)

今まで書いてきたコードに型情報はありませんので、静的型付けを導入しても、それを使うか使わないかは選択できるようにする必要があります。新たに書くコードが型情報を持っていても、型がある世界から無い世界に渡したときに型情報は失われてしまいます。失われた型情報は二度と復活しません。その結果、静的型付けを導入してもプログラムのごく一部分しか型情報を持っていないので、型チェックがほとんど行われなくなります。

一方で、JavaScriptに徹底的に型を組み込んだTypeScriptという言語があります。TypeScriptでは外部から型情報を与えることができるようになっていますので、既存のJavaScriptライブラリでも型情報を与えることができます。このような仕様を持つ言語であれば、型情報が失われることを防ぐことができます。

Rubyでも同様の対応を行うという手段がありますが、Rubyでその仕様を取り入れてしまうと別の言語になってしまうのではないかという懸念点があります。

DRY

Rubyには「重複を徹底的に取り除くべき(DRY⁠⁠」という哲学があります。このDRYを追求したときに「型宣言は重複になるのではないか」とまつもとさんは考えているそうです。

  • 「プログラムの本質は『コンピュータにどのような仕事をさせたいか』を伝えること」
  • 「型は『この手続きはこの構造を持つデータを必要とする』という情報を伝えるもの」
  • 「型が伝える情報は、既にコードの中に表現されている」
  • 「コンピュータは分かるのだから、改めて書きたくはない」

ソフトタイピング

静的型付けをそのままRubyに導入するには様々な難しい問題があることがわかりました。静的型付け以外の技術で型をチェックする方法はないのでしょうか。

いろいろと調べたところ、⁠ソフトタイピング」という技術があることがわかったそうです。

ソフトタイピングはコードを静的に解析していき、⁠この式はこういう処理が行われているため、こういう型を要求しているに違いない」と分かる範囲内で型推論を行う技術だそうです。

まずは簡単な例として、次のコードを示しました。

a=1 # type of a is Integer

このコードでは変数aに数字を代入していますので、型情報が無くても、変数aは数値型だとプログラムが判断することができます。

もう一つ例として、次のコードを取り上げました。

def foo(a)
  print a.to_int
end

foo(1)   # OK 1 has to_int
foo("a") # NG : "a" does not have to_int

fooメソッドの引数aはto_intメソッドを呼んでいます。つまり、引数aに渡すオブジェクトはto_intメソッドを持っていなければいけません。fooメソッドに1という数字を渡した場合、1はto_intメソッドを持っていますので、問題なく処理が行われます。fooメソッドに"a"という文字列を渡した場合、文字列はto_intメソッドを持っていませんので、型エラーになります。

この方法を使い、広い範囲で引数の型を調べていけば、プログラム全体の静的な解析が行えるようになります。行儀の良いコードを書いていれば、だいたいはこの方法で上手くいくのではないかと予想しているそうです。今の段階では、このソフトタイピングはRubyの部分集合であるサブセットとして提供することを考えていると述べました。

Rubyは柔軟性が高い言語ですので、動的にメソッドを定義するプログラムを書くこともできます。具体的には次の例があります。

  • requireの引数に変数を使い、動的に読み込み先を決める
  • define_methodを使い、動的にメソッドを定義する
  • method_missingで任意のメソッドに反応させる

これらの手続きを行うプログラムでは、静的な解析を行うことができなくなりますので、サブセットではメソッドに制限をかけることを検討しているそうです。

ソフトタイピングによるドキュメンテーション

ソフトタイピングによって、コンパイル時に型チェックを行うことができるようになりました。しかし、ソフトタイピングにはドキュメントとしての機能はありません。静的型付けのメリットである「ドキュメンテーション」は失われてしまうのでしょうか。

まつもとさんはソフトタイピングを導入することで「あなたが書いたプログラムはこの型であることを期待していませんか?」とプログラム側から質問するような機能を作ることができるので、これがドキュメンテーションとして機能するのではないかという考えがあると述べていました。また、エラーからドキュメントを生成したり、IDEがエラーを受け取って型を補完したりすることもできるようになるのではないかと浪漫を語っていました。

サブセット

そして、まつもとさんはソフトタイピングをRubyの部分集合であるサブセットとして提供するというアイデアを提案しました。サブセットという仕組みは様々なことに応用できるのではないかと話します。

サブセットがあると互換性を維持しながら、新しい価値を生み出すことができます。先ほどのソフトタイピングを例にすると、ソフトタイピングが有効なサブセットを使っている間は「コンパイル時に型チェックが行える」というボーナスを得ることができます。

サブセットは外すとボーナスを得られなくなる代わりに、今まで通りのRubyを使うことができるようになります。最初はサブセットを外した状態で使ってもらい、だんだんとサブセットを使ったボーナスのある世界に導いていくという方法が取れるのではないかという考えを示しました。

まとめ

今回の基調講演ではRuby 3のアイデアの中から「静的型付け」を取り上げ、⁠ソフトタイピング」⁠サブセット」に話を展開していきました。

まつもとさんは、Ruby 2がリリースされてからしばらく経ち、そろそろ新しいことを始められる頃だとし、⁠コミュニティとして死なないように、わくわくする未来を想像しましょう」というメッセージで基調講演を締めくくりました。

おすすめ記事

記事・ニュース一覧