The Go Blog

Go 2 に向けて

Russ Cox
2017年7月13日

はじめに

[これは、Gophercon 2017 で行われた私の講演のテキストです。Go 2 を議論し計画するにあたり、Go コミュニティ全体の協力を求めています。]

2007年9月25日、Rob Pike、Robert Griesemer、Ken Thompson が数日間にわたって新しいプログラミング言語について議論した後、Rob が「Go」という名前を提案しました。

翌年、Ian Lance Taylor と私がチームに加わり、私たち5人で2つのコンパイラと標準ライブラリを構築し、2009年11月10日のオープンソース公開に至りました。

その後の2年間、新しい Go オープンソースコミュニティの助けを借りて、大小さまざまな変更を試し、Go を改良し、2011年10月5日に提案されたGo 1 の計画に至りました。

Go コミュニティのさらなる助けを得て、私たちはその計画を改訂し実装し、最終的に2012年3月28日にGo 1 をリリースしました。

Go 1 のリリースは、約5年間にわたる創造的で熱狂的な努力の集大成であり、名前とアイデアのリストから安定した実用的な言語へと私たちを導きました。また、変更と混乱から安定性への明確な移行も示しました。

Go 1 に至るまでの数年間、私たちは Go を変更し、ほぼ毎週、すべての Go プログラムを壊していました。私たちは、これが Go を本番環境での使用から遠ざけていることを理解していました。本番環境では、言語の変更に対応するためにプログラムを毎週書き換えることはできません。Go 1 の発表ブログ記事が述べているように、主な動機は、信頼性の高い製品、プロジェクト、出版物(ブログ、チュートリアル、カンファレンス講演、書籍)を作成するための安定した基盤を提供し、ユーザーがプログラムが今後何年にもわたって変更なしにコンパイルおよび実行されると確信できるようにすることでした。

Go 1 がリリースされた後、私たちは Go が設計された本番環境で Go を使用する時間を費やす必要があることを知っていました。私たちは言語の変更から、自分たちのプロジェクトで Go を使用し、実装を改善することへと明確に移行しました。Go を多くの新しいシステムに移植し、Go をより効率的に実行するためにほぼすべてのパフォーマンスに重要な部分を書き換え、レース検出器などの主要なツールを追加しました。

現在、私たちは Go を使用して大規模な本番品質のシステムを構築した5年間の経験があります。何が機能し、何が機能しないかという感覚を開発しました。今こそ、Go の進化と成長の次のステップを開始し、Go の将来を計画する時です。私は今日、GopherCon の聴衆の皆さん、ビデオを見ている皆さん、または後で Go ブログを読んでいる皆さんのGoコミュニティ全員に、Go 2 を計画し実装する上で私たちと一緒に働くようお願いします。

この講演の残りの部分では、Go 2 の目標、制約と限界、全体的なプロセス、Go の使用経験、特に解決しようとする可能性のある問題に関連する経験について書くことの重要性、可能な解決策の種類、Go 2 の提供方法、そして皆さんがどのように貢献できるかを説明します。

目標

今日私たちが Go に抱く目標は、2007年と同じです。私たちはプログラマーが2種類の規模をより効果的に管理できるようにしたいと考えています。1つは本番規模で、特に多くの他のサーバーと相互作用する並行システムであり、今日ではクラウドソフトウェアに代表されます。もう1つは開発規模で、特に緩やかに連携する多くのエンジニアによって作業される大規模なコードベースであり、今日では現代のオープンソース開発に代表されます。

このような規模は、あらゆる規模の企業に現れます。5人規模のスタートアップ企業でも、他の企業が提供する大規模なクラウドベースのAPIサービスを利用したり、自社で書くソフトウェアよりも多くのオープンソースソフトウェアを利用したりすることがあります。本番規模と開発規模は、Googleだけでなく、そのスタートアップ企業にとっても同様に重要です。

Go 2 の目標は、Go が規模に対応できない最も重要な点を修正することです。

(これらの目標の詳細については、Rob Pike の2012年の記事「Go at Google: Language Design in the Service of Software Engineering」と、私の GopherCon 2015 の講演「Go, Open Source, Community」をご覧ください。)

制約

Go の目標は当初から変わっていませんが、Go の制約は確実に変化しました。最も重要な制約は、既存の Go の使用状況です。世界中には少なくとも50万人の Go 開発者がいると推定されており、これは何百万もの Go ソースファイルと少なくとも10億行の Go コードがあることを意味します。これらのプログラマーとソースコードは Go の成功を表していますが、Go 2 の主要な制約でもあります。

Go 2 は、これらすべての開発者を引き連れていかなければなりません。私たちは彼らに、大きな恩恵がある場合にのみ、古い習慣を捨てて新しい習慣を学ぶように求めなければなりません。例えば、Go 1 以前は、エラー型によって実装されるメソッドは `String` と名付けられていました。Go 1 では、エラー型と自己フォーマット可能な他の型を区別するために、`Error` に名前が変更されました。先日、私がエラー型を実装していたとき、何も考えずにメソッドを `Error` ではなく `String` と名付けてしまい、もちろんコンパイルできませんでした。5年経った今でも、古いやり方を完全に忘れていません。このような明確化のための改名は Go 1 で行うべき重要な変更でしたが、非常に良い理由がない限り、Go 2 ではあまりにも混乱を招くでしょう。

Go 2 は、既存の Go 1 のすべてのソースコードも引き継がなければなりません。Go エコシステムを分断してはなりません。Go 2 で書かれたパッケージが Go 1 で書かれたパッケージをインポートし、その逆も可能な混合プログラムは、数年にわたる移行期間中、スムーズに機能する必要があります。私たちはそれを正確にどのように行うかを突き止めなければなりません。go fix のような自動化されたツールは間違いなく役割を果たすでしょう。

混乱を最小限に抑えるためには、各変更には慎重な検討、計画、およびツールが必要であり、それによって行える変更の数が制限されます。おそらく2つか3つは可能でしょうが、5つを超えることはないでしょう。

私は、より多くの言語での識別子を許可したり、バイナリ整数リテラルを追加したりといった、些細なハウスキーピングの変更は数に入れていません。これらの些細な変更も重要ですが、正しく行うのは容易です。今日私が焦点を当てているのは、エラーハンドリングの追加サポート、immutableまたは読み取り専用値の導入、何らかのジェネリクスの追加、あるいはまだ提案されていないその他の重要なトピックといった、可能性のある大きな変更についてです。これらの大きな変更はごくわずかしかできません。慎重に選択する必要があります。

プロセス

それは重要な疑問を提起します。Go を開発するプロセスとは何でしょうか?

Go の初期の頃、私たち5人しかいなかった頃は、ガラスの壁で仕切られた隣接する共有オフィスで働いていました。問題を議論するために全員を1つのオフィスに集め、それから各自の机に戻って解決策を実装するのは簡単でした。実装中に何か問題が生じても、再び全員を集めるのは簡単でした。Rob と Robert のオフィスには小さなソファとホワイトボードがあったので、たいてい誰かがそこへ行き、ホワイトボードに例を書き始めました。たいてい例が書き上がった頃には、他の全員も自分の作業の区切りをつけ、座って議論する準備ができていました。この非公式性は、今日のグローバルな Go コミュニティには明らかにスケールしません。

Go のオープンソースリリース以来の作業の一部は、私たちの非公式なプロセスをメーリングリストや課題追跡システム、そして50万人のユーザーというより公式な世界に移植することでしたが、私たちの全体的なプロセスを明示的に説明したことは一度もないと思います。おそらく、私たちは意識的にそれについて考えたことがなかったのかもしれません。しかし、振り返ってみると、これが Go の作業の基本的なアウトラインであり、最初のプロトタイプが稼働して以来私たちが従ってきたプロセスだと思います。

ステップ1は、Go を使用し、それに関する経験を蓄積することです。

ステップ2は、解決が必要となる可能性のある Go の問題を特定し、それを明確にし、他の人に説明し、書き留めることです。

ステップ3は、その問題に対する解決策を提案し、他の人と議論し、その議論に基づいて解決策を修正することです。

ステップ4は、解決策を実装し、評価し、その評価に基づいて改良することです。

最後に、ステップ5は、その解決策をリリースし、言語、ライブラリ、または人々が日常的に使用するツールセットに追加することです。

特定の変更のために、これらすべてのステップを同じ人が行う必要はありません。実際、通常、多くの人が任意のステップで協力し、単一の問題に対して多くの解決策が提案されることがあります。また、いつでも特定のアイデアをこれ以上進めたくないと気づき、前のステップに戻ることもあります。

このプロセス全体について話したことはないと思いますが、その一部については説明してきました。2012年に Go 1 をリリースし、Go を使い始めて変更をやめる時期が来たと述べたとき、私たちはステップ1を説明していました。2015年に Go の変更提案プロセスを導入したとき、私たちはステップ3、4、5を説明していました。しかし、ステップ2を詳細に説明したことは一度もないので、今それを行いたいと思います。

(Go 1 の開発と言語変更からの移行については、Rob Pike と Andrew Gerrand の OSCON 2012 講演「The Path to Go 1」をご覧ください。提案プロセスについては、Andrew Gerrand の GopherCon 2015 講演「How Go was Made」と提案プロセスのドキュメントをご覧ください。)

問題の説明

問題を説明するには2つの部分があります。最初の部分(より簡単な部分)は、問題が正確に何であるかを述べることです。私たち開発者は、この点でかなり優れています。結局のところ、私たちが書くすべてのテストは、コンピューターでさえ理解できるほど正確な言語で、解決すべき問題の表明です。2番目の部分(より難しい部分)は、なぜその問題を解決し、解決策を維持するために時間を費やすべきなのかを誰もが理解できるほど十分に問題の重要性を説明することです。問題を正確に述べるのとは対照的に、問題の重要性を説明することはあまり多くなく、その点ではそれほど得意ではありません。コンピューターは「なぜこのテストケースが重要なのですか?これが解決する必要がある問題だと確信していますか?この問題を解決することが、あなたがすべき最も重要なことですか?」と尋ねることは決してありません。いつかそうなるかもしれませんが、今日ではありません。

2011年の古い例を見てみましょう。Go 1 を計画していたときに、`os.Error` を `error.Value` に変更することについて書いたものです。

それは、「非常に低レベルなライブラリでは、すべてが `os.Error` のために `os` をインポートする」という、問題の正確な1行の記述から始まります。次に、私が下線を引いた5行があり、問題の重要性を説明するために書かれています。「`os` が使用するパッケージは、それ自体が API でエラーを提示できず、他のパッケージはオペレーティングシステムサービスとは関係のない理由で `os` に依存する」というものです。

これら5行は、あなたにこの問題が重要であると確信させますか?それは、私が省略した文脈をどれだけうまく補完できるかにかかっています。理解されるためには、他の人が知る必要があることを予測する必要があります。当時の私の聴衆、つまりそのドキュメントを読んでいたGoogleのGoチームの他の10人にとって、その50語で十分でした。昨年のGothamGoの聴衆、つまりはるかに多様な背景と専門分野を持つ聴衆に同じ問題を提示するには、より多くの文脈を提供する必要があり、私は約200語に加えて、実際のコード例と図を使用しました。同僚と話すときには省略するであろう、具体的な例で特に示される文脈を追加することが、今日のGoのグローバルコミュニティにおいて、どんな問題の重要性を説明するためにも必要であるという事実があります。

問題が重要であることを他者に納得させることは、不可欠なステップです。問題が重要でないと見なされると、ほとんどすべての解決策が高価すぎると感じられます。しかし、重要な問題には、通常、合理的なコストで多くの解決策が存在します。特定の解決策を採用すべきかどうかで意見が対立するとき、私たちはしばしば、解決しようとしている問題の重要性について意見が対立しています。これは非常に重要なので、少なくとも後から見れば明確に示される2つの最近の例を見てみましょう。

例:うるう秒

最初の例は時間に関するものです。

あるイベントにかかる時間を計測したいとします。開始時間を記録し、イベントを実行し、終了時間を記録し、そして終了時間から開始時間を引きます。イベントが10ミリ秒かかった場合、減算の結果は10ミリ秒(おそらくわずかな測定誤差の範囲内)となります。

start := time.Now()       // 3:04:05.000
event()
end := time.Now()         // 3:04:05.010

elapsed := end.Sub(start) // 10 ms

この自明な手順は、うるう秒の間に失敗することがあります。私たちの時計が地球の自転と完全に同期していない場合、うるう秒(公式には午後11時59分60秒)が真夜中の直前に挿入されます。うるう年とは異なり、うるう秒には予測可能なパターンがないため、プログラムやAPIに組み込むのが困難です。時折発生する61秒の分を表現しようとする代わりに、オペレーティングシステムは通常、真夜中の直前に時計を1秒戻すことでうるう秒を実装し、午後11時59分59秒が2回発生するようにします。この時計のリセットにより、時間が逆行しているように見え、そのため私たちの10ミリ秒のイベントが-990ミリ秒と計測される可能性があります。

start := time.Now()       // 11:59:59.995
event()
end := time.Now()         // 11:59:59.005 (really 11:59:60.005)

elapsed := end.Sub(start) // –990 ms

このように時計のリセットをまたぐイベントのタイミングを計るには、時刻時計は不正確であるため、オペレーティングシステムは現在、2つ目の時計、つまり単調時計を提供しています。これは絶対的な意味はありませんが、秒を数え、決してリセットされません。

奇妙な時計のリセット時を除けば、単調時計は時刻時計よりも優れているわけではなく、時刻時計には時間を知るのに役立つという追加の利点があるため、Go 1 の時間 API は簡潔さのために時刻時計のみを公開しています。

2015年10月、バグレポートにより、Go プログラムが、特に一般的なうるう秒のような時計のリセットをまたぐイベントを正しく計測できないことが指摘されました。提案された修正は、元の課題タイトルと同じく「単調時計ソースにアクセスするための新しい API を追加する」というものでした。私は、この問題は新しい API を正当化するほど重要ではないと主張しました。数ヶ月前、2015年半ばのうるう秒のために、Akamai、Amazon、Google は一日中わずかに時計を遅らせ、時計を戻すことなく追加の秒を吸収しました。この「リープスメア」アプローチの最終的な広範な採用は、本番システムにおけるうるう秒の時計リセット問題を排除するように思われました。対照的に、Go に新しい API を追加することは新しい問題を引き起こします。2種類の時計を説明し、いつそれぞれを使用するかをユーザーに教育し、既存のコードの多くの行を変換する必要があるでしょう。これらすべては、まれにしか発生せず、おそらく自然に解決する可能性のある問題のためです。

明確な解決策がない問題が発生したときに、私たちはいつもやっていることをしました。待ちました。待つことで、問題に関する経験と理解を深める時間が得られ、また良い解決策を見つける時間も増えます。このケースでは、待つことで問題の重要性に関する理解が深まりました。それは、幸いにもCloudflareでの軽微な停止という形で現れました。彼らのGoコードは、2016年末のうるう秒中にDNSリクエストの時間を約-990ミリ秒と計測し、それが彼らのサーバー全体で同時にパニックを引き起こし、ピーク時にはDNSクエリの0.2%を破壊しました。

Cloudflareは、Goが意図されたまさにクラウドシステムであり、Goがイベントを正確に計測できないことに基づく本番環境での停止が発生しました。そして、これが重要な点ですが、Cloudflareは彼らの経験をJohn Graham-Cummingによる「うるう秒がCloudflare DNSにどのように、そしてなぜ影響を与えたか」というブログ記事で報告しました。JohnとCloudflareは、本番環境でのGoの使用経験の具体的な詳細を共有することで、うるう秒の時計リセットをまたぐ正確なタイミングの問題が、修正せずに放置するにはあまりにも重要であることを私たちが理解するのに役立ちました。その記事が公開されてから2ヶ月後、私たちはGo 1.9で出荷されるソリューションを設計し実装しました(実際、新しいAPIなしで実現しました)。

例:エイリアス宣言

2番目の例は、Go におけるエイリアス宣言のサポートです。

ここ数年、Googleでは大規模なコード変更に焦点を当てたチームが設立されました。これは、C++、Go、Java、Pythonなどの言語で書かれた何百万ものソースファイルと何十億ものコード行からなる私たちのコードベース全体にAPI移行やバグ修正を適用することを意味します。そのチームの仕事から学んだことの一つは、APIをある名前から別の名前に変更する際に、クライアントコードを一度にすべてではなく、複数のステップで更新できることの重要性です。これを行うには、古い名前の使用を新しい名前へ転送する宣言を記述できる必要があります。C++には、この転送を可能にする#define、typedef、およびusing宣言がありますが、Goには何もありません。もちろん、Goの目標の一つは大規模なコードベースにうまくスケールすることであり、GoogleでのGoコードの量が増えるにつれて、何らかの転送メカニズムが必要であること、そして他のプロジェクトや企業もGoコードベースの成長に伴ってこの問題に直面するであろうことが明らかになりました。

2016年3月、私はRobert GriesemerとRob PikeとGoがコードベースの段階的な更新をどのように処理できるかについて話し始め、まさに必要な転送メカニズムであるエイリアス宣言にたどり着きました。この時点で、Goの進化の仕方に非常に良い感触を抱きました。Goの初期の頃からエイリアスについて話していましたが、実際、最初の仕様ドラフトにはエイリアス宣言を使用した例があります。しかし、エイリアス、そして後に型エイリアスについて議論するたびに、明確な使用例がなかったため、それらを省略していました。今、私たちはエイリアスを追加することを提案していました。それはエレガントな概念だからではなく、スケーラブルなソフトウェア開発というGoの目標を達成する上で重大な実際的な問題を解決するからです。これがGoの将来の変更のモデルとなることを望みました。

その年の春の後半、Robert と Rob は提案書を書き、Robert はそれをGophercon 2016 のライトニングトークで発表しました。その後の数ヶ月は順調にはいかず、Go の将来の変更のモデルとは全く異なるものでした。私たちが学んだ多くの教訓の一つは、問題の重要性を説明することの重要性でした。

少し前、私は皆さんにこの問題について説明し、それがどのように発生し、なぜ発生するのかについて背景を説明しましたが、いつか皆さんに影響を与える可能性があるかどうかを評価するのに役立つ具体的な例はありませんでした。昨年の提案とライトニングトークでは、C、L、L1、C1からCnというパッケージを含む抽象的な例が提示されましたが、開発者が関連付けられる具体的な例はありませんでした。その結果、コミュニティからのフィードバックのほとんどは、エイリアスがGoogleの特定の問題を解決するだけで、他の誰もが抱える問題ではないという考えに基づいていました。

Googleが当初うるう秒の時刻リセットを正しく処理することの重要性を理解していなかったように、私たちは大規模な変更中に段階的なコード移行と修復を処理することの重要性を、より広範なGoコミュニティに効果的に伝えることができませんでした。

秋に私たちはやり直しました。私は講演を行い、オープンソースコードベースから複数の具体的な例を引用して問題を提示する記事を書きました。これは、この問題がGoogle内だけでなく、いたるところで発生することを示しています。より多くの人々が問題を理解し、その重要性を認識できるようになったことで、どのような解決策が最善かについて生産的な議論ができました。その結果、型エイリアスGo 1.9 に含まれることになり、Go がより大規模なコードベースにスケールするのに役立つでしょう。

経験レポート

ここでの教訓は、異なる環境で働く人が理解できる方法で問題の重要性を説明することは困難ですが、不可欠であるということです。コミュニティとしてGoへの主要な変更を議論するためには、解決したい問題の重要性を説明することに特に注意を払う必要があります。その最も明確な方法は、Cloudflareのブログ記事私のリファクタリング記事のように、その問題が実際のプログラムや実際の生産システムにどのように影響するかを示すことです。

このような経験レポートは、抽象的な問題を具体的なものに変え、その重要性を理解するのに役立ちます。また、テストケースとしても機能します。提案されたソリューションは、レポートが記述する実際の現実世界の問題への影響を調べることで評価できます。

たとえば、最近ジェネリクスを検討していますが、Go ユーザーがジェネリクスで解決する必要がある詳細で具体的な問題の明確なイメージが私にはありません。その結果、ジェネリックメソッドをサポートするかどうか、つまりレシーバーとは別にパラメータ化されたメソッドをサポートするかどうかといった設計上の質問に答えることができません。もし私たちが多くの実際の使用例を持っていれば、重要なものを調べることで、このような質問に答え始めることができるでしょう。

別の例として、エラーインターフェースを様々な方法で拡張する提案を目にしましたが、大規模なGoプログラムがエラーをどのように理解し処理しようとしているかを示す経験レポートは見たことがありません。ましてや、現在のエラーインターフェースがそれらの試みをどのように妨げているかを示すレポートもありません。これらのレポートは、問題の詳細と重要性を私たち全員がよりよく理解するのに役立つでしょう。それは解決する前に必ず行わなければなりません。

私は続けられます。Go への主要な潜在的変更はすべて、今日人々が Go をどのように使用し、なぜそれが十分に機能していないかを文書化した1つ以上の経験レポートによって動機付けられるべきです。Go で検討する可能性のある明白な主要な変更については、そのようなレポート、特に実際の例で示されたレポートはあまり知りません。

これらのレポートは Go 2 提案プロセスの生の資料であり、Go の経験を理解するのに役立つよう、皆さん全員にそれらを書いていただく必要があります。皆さんは50万人いて、幅広い環境で働いていますが、私たちの数はそれほど多くありません。自分のブログに投稿するか、Medium の記事を書くか、GitHub Gist を書くか(Markdown 用に `.md` ファイル拡張子を追加してください)、Google ドキュメントを書くか、その他お好きな公開メカニズムを使用してください。投稿後、新しい Wiki ページ golang.org/wiki/ExperienceReports に投稿を追加してください。

解決策

これで、解決すべき問題をどのように特定し説明するかを理解したので、すべての問題が言語の変更によって最もよく解決されるわけではないこと、そしてそれはそれで良いことであることを簡単に述べたいと思います。

私たちが解決したい問題の一つは、コンピュータが基本的な算術演算中にしばしば追加の結果を計算できるにもかかわらず、Go がそれらの結果に直接アクセスする手段を提供していないことです。2013年、Robert は、2つの結果(「カンマOK」)式のアイデアを基本的な算術に拡張することを提案しました。たとえば、x と y が uint32 の値である場合、`lo, hi = x * y` は、通常の下位32ビットだけでなく、積の上位32ビットも返します。この問題は特に重要ではないように思われたため、私たちは潜在的な解決策を記録しましたが、実装しませんでした。私たちは待ちました。

より最近では、Go 1.9 のために様々なビット操作関数を含むmath/bits パッケージを設計しました。

package bits // import "math/bits"

func LeadingZeros32(x uint32) int
func Len32(x uint32) int
func OnesCount32(x uint32) int
func Reverse32(x uint32) uint32
func ReverseBytes32(x uint32) uint32
func RotateLeft32(x uint32, k int) uint32
func TrailingZeros32(x uint32) int
...

このパッケージには各関数の優れた Go 実装がありますが、コンパイラは利用可能な場合、特別なハードウェア命令に置き換えることも行います。この math/bits の経験に基づいて、Robert と私は今、言語を変更して追加の算術結果を利用可能にすることは賢明ではなく、代わりに math/bits のようなパッケージで適切な関数を定義すべきだと考えています。ここで最良の解決策は、言語の変更ではなくライブラリの変更です。

Go 1.0 の後、解決したかったかもしれない別の問題は、ゴルーチンと共有メモリが Go プログラムにレースを導入しやすくしすぎ、本番環境でクラッシュやその他の誤動作を引き起こすという事実でした。言語ベースの解決策は、データ競合を禁止する方法を見つけ、データ競合のあるプログラムを記述すること、あるいは少なくともコンパイルすることを不可能にすることでした。それを Go のような言語にどのように組み込むかは、プログラミング言語の世界ではまだ未解決の問題です。代わりに、主要なディストリビューションにツールを追加し、簡単に使用できるようにしました。そのツール、レース検出器は、Go の経験に不可欠な部分となりました。ここで最良の解決策は、言語の変更ではなく、ランタイムとツールの変更でした。

もちろん、言語の変更も行われますが、すべての問題が言語で最もよく解決されるわけではありません。

Go 2 のリリース

最後に、Go 2 はどのように出荷され、提供されるのでしょうか?

最高の計画は、Go 2 の後方互換性のある部分を、Go 1 リリースシーケンスの一部として、機能ごとに段階的に出荷することだと思います。これにはいくつかの重要な特性があります。第一に、Go 1 リリースを通常のスケジュールに保ち、ユーザーが現在依存しているタイムリーなバグ修正と改善を継続することです。第二に、Go 1 と Go 2 の間の開発努力の分割を避けることです。第三に、Go 1 と Go 2 の間の乖離を避け、全員の最終的な移行を容易にすることです。第四に、一度に一つの変更に集中して提供することを可能にし、品質維持に役立つはずです。第五に、後方互換性のある機能を設計することを奨励するでしょう。

Go 1 リリースに何らかの変更が適用され始める前に、議論と計画に時間が必要ですが、約1年後、Go 1.12あたりで軽微な変更が見られるようになるのは妥当に思えます。それによって、パッケージ管理のサポートを最初に実現する時間も得られます。

後方互換性のある作業がすべて完了したら、例えば Go 1.20 で、Go 2.0 で後方互換性のない変更を行うことができます。もし後方互換性のない変更がないと判明した場合、Go 1.20 が Go 2.0 であると宣言するだけかもしれません。いずれにせよ、その時点で Go 1.X リリースシーケンスの作業から Go 2.X シーケンスの作業に移行し、最終的な Go 1.X リリースには延長サポート期間が設けられるかもしれません。

これはすべてやや憶測であり、私が述べた特定のリリース番号は概算のプレースホルダーにすぎませんが、Go 1 を放棄するつもりはなく、可能な限り Go 1 を維持していくことを明確にしたいと考えています。

協力のお願い

皆様のご協力が必要です。

Go 2 に関する議論は今日から始まり、メーリングリストやイシュートラッカーなどの公開フォーラムでオープンに行われます。あらゆる段階でご協力をお願いいたします。

今日、最も必要なのは経験レポートです。Go があなたにとってどのように機能しているか、そしてもっと重要なこととして、どのように機能していないかを教えてください。ブログ記事を書き、実際の例、具体的な詳細、実際の経験を含めてください。そして、それを私たちのWiki ページにリンクしてください。それが、私たちGoコミュニティがGoについて何を変えたいかについて話し始める方法です。

ありがとうございます。

次の記事:コントリビューターサミット
前の記事:開発者体験ワーキンググループの紹介
ブログインデックス