Goブログ

Go 2、いよいよ登場!

Robert Griesemer
2018年11月29日

背景

GopherCon 2017で、Russ Coxは彼の講演「Goの未来」(ブログ記事)を通して、Goの次期メジャーバージョンに関する検討を正式に開始しました。我々は、この将来の言語を非公式にGo 2と呼んでいますが、それが大きな変化と単一のメジャーリリースではなく、段階的なステップで到着することを今では理解しています。それでも、Go 2は、将来の言語について話す方法として有用な名称であり、今のところは使い続けましょう。

Go 1とGo 2の大きな違いは、設計に影響を与える人々と、意思決定の方法です。Go 1は外部からの影響が控えめな少人数チームによる取り組みでしたが、Go 2ははるかにコミュニティ主導となります。約10年間の公開を経て、当初は知らなかった言語とライブラリについて多くのことを学びました。これは、Goコミュニティからのフィードバックがあってこそ可能になったことです。

2015年、私たちは言語とライブラリの変更に関する提案を集めるために、提案プロセスを導入しました。上級Goチームメンバーで構成される委員会が、定期的に受信した提案をレビュー、分類、決定してきました。これはかなりうまく機能しましたが、そのプロセスの一環として、後方互換性のないすべての提案を無視し、単にGo 2とラベル付けしていました。2017年には、Go 2の全体像を考慮したより包括的な計画に沿って、どれだけ小さなものであっても、増分的な後方互換性のある言語の変更も行うことをやめました。

今こそGo 2の提案を実行する時ですが、そのためにはまず計画が必要です。

現状

執筆時点では、Go 2提案としてラベル付けされた未解決の課題が約120件あります(Go 2提案としてラベル付けされた未解決の課題)。それぞれが、既存のGo 1互換性保証を満たしていないことがよくある、重要なライブラリまたは言語の変更を提案しています。Ian Lance Taylorと私はこれらの提案を精査し、(Go2CleanupNeedsDecisionなど)分類することで、現状を把握し、それらを処理しやすくしました。また、関連する提案をマージし、Goの範囲外であるか、実行不可能であると判断されたものを閉じました。

残りの提案からのアイデアは、Go 2のライブラリと言語に影響を与える可能性が高いです。初期段階で浮上してきた2つの主要なテーマは、エラー処理の改善とジェネリクスです。これらの2つの分野に関するドラフト設計が今年のGopherConで公開されており、さらなる検討が必要です。

しかし、残りの部分はどうでしょうか?私たちは制約されています。なぜなら、現在何百万人ものGoプログラマーと膨大な量のGoコードが存在し、エコシステムの分裂を避けるために、すべてを考慮する必要があるからです。つまり、多くの変更を行うことができず、行う変更は慎重に選択する必要があります。進捗を図るために、これらの重要な潜在的な変更について、新しい提案評価プロセスを実施しています。

提案評価プロセス

提案評価プロセスの目的は、最終決定を行うことができるように、少数の厳選された提案に関するフィードバックを収集することです。このプロセスは、リリースサイクルとほぼ並行して実行され、以下の手順で構成されています。

  1. 提案の選定。Goチームは、最終決定を行うことなく、採択を検討する価値があると見える少数のGo 2提案を選択します。選定基準の詳細については、以下を参照してください。

  2. 提案に対するフィードバック。Goチームは、選定された提案をリストしたお知らせを送信します。お知らせでは、選定された提案を進める暫定的な意図と、各提案に対するフィードバックを収集することをコミュニティに説明します。これにより、コミュニティは提案を行い、懸念事項を表明する機会を得ます。

  3. 実装。そのフィードバックに基づいて、提案が実装されます。これらの重要な言語とライブラリの変更の目標は、次のリリースサイクルの初日に提出できる状態にすることです。

  4. 実装に対するフィードバック。開発サイクル中に、Goチームとコミュニティは、新機能を試用し、さらにフィードバックを収集する機会を得ます。

  5. リリース決定。3ヶ月間の開発サイクルの終了時(リリース前の3ヶ月間のリポジトリ凍結の開始時)、そしてリリースサイクル中に収集された経験とフィードバックに基づいて、Goチームは各変更をリリースするかどうかについての最終決定を行います。これは、変更が期待されるメリットをもたらしたか、予期せぬコストが生じたかを検討する機会を提供します。リリースされると、変更は言語とライブラリの一部になります。除外された提案は、検討に戻されるか、完全に却下される可能性があります。

2回のフィードバックラウンドにより、このプロセスは提案の却下を重視しており、これにより機能の追加が抑制され、言語を小さくクリーンに保つのに役立つでしょう。

未解決のGo 2提案すべてについてこのプロセスを実行することはできません。提案が多すぎるからです。そこで、選定基準が役割を果たします。

提案の選定基準

提案は、少なくとも以下の条件を満たす必要があります。

  1. 多くの人にとって重要な問題に対処する,

  2. 他の人への影響を最小限にする、そして

  3. 明確かつよく理解された解決策を提示する.

要件1は、私たちが行う変更が可能な限り多くのGo開発者を支援することを保証します(コードをより堅牢にし、書きやすくし、正しくなる可能性を高めるなど)。一方、要件2は、プログラムの破損やその他の混乱を引き起こすことによって、可能な限り少ない開発者に悪影響を与えないように注意することを保証します。経験則として、特定の変更によって害を受ける開発者の数よりも、少なくとも10倍以上の開発者を支援することを目指すべきです。実際のGoの使用に影響を与えない変更は、大きな実装コストに対して正味ゼロのメリットであり、避けるべきです。

要件3がないと、提案の実装ができません。たとえば、ジェネリックのある形式が多くの人の重要な問題を解決する可能性があると信じていますが、まだ明確かつよく理解された解決策はありません。それは問題ありません。提案は、検討される前に設計図に戻される必要があるだけです。

提案

これは私たちにとってうまく機能する優れた計画であると感じていますが、これが出発点にすぎないことを理解することが重要です。このプロセスを使用する中で、うまく機能しない方法を発見し、必要に応じて改善していきます。重要な点は、実際使用するまで、どのように改善できるかわからないということです。

小さな数の後方互換性のある言語提案から始めるのが安全な方法です。長い間言語の変更を行っていなかったので、これによりそのモードに戻ることができます。また、変更によって既存のコードを壊すことを心配する必要がなく、完璧な試金石となります。

以上の点を踏まえ、Go 1.13リリースのために、以下のGo 2提案を選定します(提案評価プロセスのステップ1)。

  1. #20706 Unicode TR31に基づく一般的なUnicode識別子:これは、非西洋のアルファベットを使用するGoプログラマーにとって重要な問題に対処し、他の人への影響はほとんどまたは全くありません。正規化に関する質問に答える必要があり、コミュニティからのフィードバックが重要になります。しかし、その後は実装方法はよく理解されています。識別子のエクスポートルールはこの影響を受けません。

  2. #19308#28493 2進整数リテラルと数値リテラルでの_のサポート:これらは、多くのプログラマーの間で非常に人気のある比較的マイナーな変更です。「重要な問題」を解決するというしきい値に達しない可能性がありますが(16進数はこれまでうまく機能しています)、これによりGoは他のほとんどの言語と同等になり、一部のプログラマーの悩みの種を解消します。2進整数リテラルや数値フォーマットに関心のない他の人への影響は最小限であり、実装方法はよく理解されています。

  3. #19113 シフトカウントとして符号付き整数を許可する:非定数のシフトのおよそ38%が(人工的な)uint変換を必要とします(詳細な内訳については、問題を参照してください)。この提案により、多くのコードをクリーンアップし、シフト式をインデックス式や組み込み関数capとlenとより同期させることができます。コードへの影響はほとんど肯定的です。実装方法はよく理解されています。

次のステップ

このブログ投稿により、提案評価プロセスの最初のステップと2番目のステップを実行しました。上記の課題に関するフィードバックを提供するのは、あなた、Goコミュニティ次第です。

明確で承認されたフィードバックのある提案については、すべて実装に進みます(プロセスのステップ3)。変更を次回リリースサイクルの初日(暫定的に2019年2月1日)に実装したいと考えているため、今回は2ヶ月間のフィードバック期間(2018年12月、2019年1月)を確保するために、実装を少し早める場合があります。

3ヶ月の開発サイクル(2019年2月~5月)では、選択された機能が実装され、tipで利用可能になり、誰もがそれらを使用して経験を積むことができます。これにより、フィードバックを得るもう1つの機会が生まれます(プロセスのステップ4)。

最後に、リポジトリフリーズ(2019年5月1日)直後に、Goチームは新しい機能を今後も継続するか(そしてGo 1互換性保証に含めるか)、それとも廃止するか(プロセスの最終ステップ)の最終決定を行います。

(リポジトリをフリーズしたまさにその時点で機能の削除が必要になる可能性が実際にあるため、実装は、システムの他の部分を不安定にすることなく機能を無効化できるようなものでなければなりません。言語の変更では、すべての機能関連コードが内部フラグによって保護されていることを意味する場合があります。)

これはこのプロセスに従う初めての試みとなるため、リポジトリフリーズは、プロセスを振り返り、必要に応じて調整する絶好の機会にもなります。うまくいくかどうか見てみましょう。

評価を楽しんでください!

次の記事:Go Modules in 2019
前の記事:Goの9年間
ブログインデックス