ジェネリクスの次のステップ
The Next Step for Generics by Ian Lance Taylor and Robert Griesemer
はじめに
Goへジェネリクスを追加する可能性について前回書いてから、ほぼ1年が経ちました。そろそろ近況をお伝えする頃合いです。
更新された設計
私たちはジェネリクスの設計ドラフトを継続して改良してきました。設計ドラフトに記述されているジェネリクスを使ったGoコードをパースして型エラーを報告できるプログラム、つまり型チェッカーを実装しました。サンプルコードも書きました。そして非常に多くの方々からフィードバックを集めました。提供してくださった皆さん、ありがとうございます!
そこから学んだことをもとに、更新版の設計ドラフトを公開します。最大の変更点は、contract(契約)という考え方を取り下げたことです。contractとインターフェース型の違いはわかりにくいものだったため、その違いをなくすことにしました。型パラメータは今後インターフェース型によって制約されます。インターフェース型は、制約として使われる場合に限り、型リストを含められるようになりました(これまでの設計ドラフトでは、型リストはcontractの機能でした)。より複雑なケースでは、パラメータ化されたインターフェース型を使うことになります。
この設計ドラフトを、より単純でわかりやすいものだと感じてもらえれば幸いです。
実験用ツール
設計ドラフトをさらに改良していく判断材料とするため、変換ツールを公開します。このツールを使うと、設計ドラフトに記述されているバージョンのジェネリクスで書かれたコードの型チェックと実行ができます。このツールはジェネリックなコードを通常のGoコードへ変換することで動作します。この変換処理にはいくつかの制限がありますが、ジェネリックなGoコードがどのようなものになりそうか感触をつかむには十分だと考えています。もしジェネリクスが言語仕様として採用された場合、実際の実装はこれとは異なる方式になります(コンパイラに直接実装する方式については、まだ検討を始めたばかりです)。
このツールは、Go Playgroundの派生版として https://go2goplay.golang.org で利用できます。このPlaygroundは通常のGo Playgroundと同じように動作しますが、ジェネリックなコードにも対応しています。
自分でツールをビルドして使うこともできます。このツールはGo本体リポジトリのブランチで公開されています。ソースからGoをインストールする手順に従ってください。ただし、最新のリリースタグをチェックアウトするよう指示されている箇所では、代わりに git checkout dev.go2go を実行してください。あとは指示どおりにGoツールチェインをビルドしてください。
変換ツールについてはREADME.go2goに文書化されています。
次のステップ
このツールによって、Goコミュニティがジェネリクスを試す機会を得られることを願っています。私たちが学びたいことは主に2つあります。
まず、ジェネリックなコードが理にかなっているかどうかです。それはGoらしく感じられるでしょうか。どのような驚きに遭遇するでしょうか。エラーメッセージは役に立つでしょうか。
次に、多くの人が「Goにはジェネリクスが必要だ」と言ってきたことは知っていますが、それが具体的に何を意味するのかを私たちは必ずしも把握できていません。この設計ドラフトは、その問題に有用な形で対処できているでしょうか。「Goにジェネリクスがあればこの問題を解決できるのに」と思うような問題があるなら、このツールを使ってその問題を解決できるでしょうか。
私たちはGoコミュニティから集めたフィードバックをもとに、今後どう進めるかを決定します。もしこの設計ドラフトが好意的に受け止められ、大きな変更が不要であれば、次のステップは正式な言語変更の提案になります。念のためお伝えしておくと、もし誰もがこの設計ドラフトに完全に満足し、それ以上の調整が一切不要だったとしても、ジェネリクスがGoに追加される最速のタイミングは、2021年8月にリリース予定のGo 1.17になります。もちろん実際には予期しない問題が起こりうるため、これはあくまで楽観的な見通しであり、確定的な予測はできません。
フィードバック
言語仕様の変更についてフィードバックを提供する最善の方法は、メーリングリスト golang-nuts@googlegroups.com です。メーリングリストは完璧な手段ではありませんが、最初の議論の場としては最良の選択肢だと考えています。設計ドラフトについて書く際は、件名の先頭に [generics] と入れ、話題ごとに別のスレッドを立てるようにしてください。
ジェネリクスの型チェッカーや変換ツールにバグを見つけた場合は、通常のGoのIssueトラッカーであるgo.dev/issueに登録してください。Issueのタイトルは cmd/go2go: で始めてください。なお、Issueトラッカーはスレッド機能がなく長い議論には向いていないため、言語仕様の変更について議論する場としては最適ではないことに注意してください。
皆さんからのフィードバックをお待ちしています。
謝辞
まだ完成はしていませんが、ここまで長い道のりを歩んできました。多くの方々の助けなしには、ここまで到達できませんでした。
Philip Wadler氏と共同研究者の方々には、Goにおけるジェネリクスを形式的に検討し、設計の理論的な側面を明確にする手助けをしていただいたことに感謝します。彼らの論文Featherweight Goは、制限されたバージョンのGoにおけるジェネリクスを分析しており、GitHub上でプロトタイプも公開しています。
また、以前のバージョンの設計ドラフトに詳細なフィードバックを寄せてくださった方々にも感謝します。
そして最後になりましたが、Goチームの多くのメンバー、Go Issueトラッカーへの多くの貢献者、そしてこれまでの設計ドラフトに対してアイデアやフィードバックを共有してくださったすべての方々に感謝します。私たちはそのすべてに目を通しており、大変感謝しています。皆さんなしにはここまで来られませんでした。
By Ian Lance Taylor and Robert Griesemer