Chapter 02無料公開

Go に足らなかった物

mattn
mattn
2020.09.21に更新

これまでの経緯

今年、Go はバージョン1がリリースされてから11年目になろうとしています。元々 Go の立ち位置は Better C と呼ばれていました。一見モダンには見えますが、文法や標準で用意されているライブラリの設計方針はとてもC言語に寄っていて一部のユーザにはとてもウケが良いのですが、評判は二極化しており一部では「Go はモダンではない」「Go 言語には○○が無い」という意見をお持ちの方も幾らか見られました。その理由の一つが Generics です。Go はこれまで Generics を持ち合わせていませんでした。それは何故でしょうか。

保守的な言語 Go

Go 開発チームはとても保守的で、実は初期の設計からあまり大きな言語仕様の変更を行ってきませんでした。開発者の皆さんの意見を聞いて、開発者が本当に望んでいる物をリリースする方針を貫いてきました。そしてこの方針は「プログラミング言語 Go を壊さない」という結果をもたらしました。
この事は Go を生んだ開発者 Rob Pike 氏のインタビューでも語られています。

https://evrone.com/rob-pike-interview

The political success was the firm promise made about compatibility for Go version 1. Once we, and the community, had used Go for a few years, we had a long list of things we wanted to fix, but change is disruptive. So we did a careful program of updates, with the "go fix" command to pull the community along, and once that was done, not only did we stop, we promised to stay stopped. That stability - Go programs written in 2012 will still compile and run perfectly today - was a huge enabler for growth. Companies could use the language with confidence that we would not break their software. The adoption rate increased dramatically after version 1 and its compatibility promise appeared. And although we have since learned of many other things we would like to change, we can't break existing programs, and we are fine with that.

政治的に成功と言える物として、Go のバージョン1との互換性についてしっかりと約束した事が挙げられます。我々とコミュニティが数年間 Go を使い続けた結果、修正したいと思う事が山ほどありましたが、それらの変化は破壊的な物でした。そこで我々はコミュニティを引っ張っていくために、"go fix" コマンドを使って慎重にプログラムの更新をを実施しましたが、それが完了した後に我々は、その更新をやめるだけでなく以降、言語の変更を停止し続ける事を約束しました。この安定性(2012年に書かれたGoプログラムは、今日でも完璧にコンパイルされ、実行されます)は、成長の為の大きな原動力となりました。企業は我々が自社のソフトウェアを壊すことはないという確信を持って、この言語を使用することができました。バージョン1が登場し、互換性が約束されるようになると、Go の採用率は劇的に上昇しました。それ以降も変更したい事が沢山あった事を知りましたが、既存のプログラムを壊すことはできませんし、我々はそれで構わないと思いました。

この方針はとても大きな成功をもたらしました。しかしその反面、幾らかの弊害も生んできました。

Go 開発チームのこの方針は皆が望んでいたであろう Generics の導入タイミングを遅らせ、これまで Go で少ししかコードを書いた事がなかったユーザの皆さんに「Go は Generics がない」と言わせてしまう状態を生んでしまっていました。

なぜ導入が遅れたか

もちろん Go が変更を許さない言語であった事は理由でしたが、Go に Generics がなかなか入らなかった理由として、Go そのものの生い立ちが起因していると筆者は思っています。

C言語を書いた事がある方ならば、任意の型の配列を特定の条件を元にフィルタする様なコードを書く際には、自分でその型にあったループを書かないといけない、またはマクロを駆使してそれっぽく実装するしかない、という事は分かって頂けるかと思います。
これは Go が良くも悪くも Better C であるという縛りがそうしていたのであろうと推測します。なにせC言語出身で Go を書き始めた人達からすると「あぁ、ループを書けばいいじゃんC言語の様に」となってしまうのですから。
我々 Go ユーザがもっと Generics が欲しいとアピールしていれば、もっと早く Generics が導入されたかもしれません。

Generics を導入する提案が採用されて以降、かなり活発な議論が行われ、Go らしい Generics、軽い Generics、他の言語に引けを取らない Generics の案が沢山出されました。以下の URL からその膨大な量の議論や提案を参照する事ができます。

https://github.com/golang/go/wiki/Go2GenericsFeedback#supplemental-supporting-with-modifications