Go
golang
Go言語

なぜGo言語は成功を収めることができたのか - Googleの人が語る(翻訳)

Screen Shot 2018-06-19 at 21.10.59.png

Goの特徴となぜGoがここまで成功したかをGoogleの方がまとめたスライドがとても「簡潔」で分かりやすかったので、翻訳(要約)してまとめてみました。

Go使いとして、Goの思想を捉えた上で開発を進めていきたいです。

Rob Pike, "Simplicity is Complicated", 2015

なぜGoは成功したか

  • コンパイルのスピード
  • 実行スピード
  • デプロイ
  • ツール
  • ライブラリ

など多くの理由があげられそうだが、これらは言語の特徴であり、重要ではあるが本当の答えではない。

私の答えは、Simplicity(簡潔さ)である。

Java, JavaScript (ECMAScript), Typescript, C#, C++, Hack (PHP)などの話を聞いていると、これらの言語は互いに特徴を取り入れ合っている。あたかも、1つの巨大な言語に収束しようとしている。

言語仕様は、考え方に影響を与える。自然言語と同じである。コンピュータ言語であれば、オブジェクト指向プログラミング・関数型プログラミングなどである。

上のように、様々な言語が1つのものに収束しようとするとき、我々も考え方が1つに収束してしまう。しかし、考え方の多様性は良いものであり、それぞれの問題に対してそれぞれ言語が存在するべきである。ツールは1つだけであるより、タスクに対してベストなツールを選んでいくべきである。

上にあげたような言語は、特徴を次々と追加することで、進化に完成に向かっている。それぞれ似たような言語になりながら、どんどんと複雑になっている。区別をしっかりとつけないまま肥大化しているだけである。

しかし、Goは違う。Goを初めて触った人から他言語の特徴がなぜ入っていないのかなどの質問をよく受けるが、Goは他の言語のようになろうと特徴を追加したりしない。特徴を追加していくことがGoを良くすることだとは思っていない、ただ肥大化させるだけである。そして、GoはGoとしての特徴を徐々に失っていき、面白くなくなっていく。

読みやすさ|Readability

言語に特徴が多すぎると、書かれているコードがそのように動く理由がわからなくなる。言語が複雑さを増すと、単純に理解しにくくなるのだ。特徴が増えると複雑になるだけだ、simplicity(簡潔な)方がいい。特徴が増えると読みにくい。readability(読みやすい)方がいい。

そして、読みやすいコードだと理解しやすい、取り組みやすい、修正しやすい、つまり信頼できるのである。

表現力|Expressiveness

簡潔であればあるほど表現力は高くなるが、読みやすいとは限らない。例えば、以下のコードはとても表現力が高いと言える。

Consider APL: ⊃ 1 ω ∨ . ∧ 3 4 = +/ +⌿ 1 0 ‾1 ∘.θ 1 - ‾1 Φ″ ⊂ ω

しかし、読みにくいし、何を言いたいのか分からない。表現力と簡潔さと読みやすさを共に追求していくことが大切である。

Goのゴール

Goは、大きなクラウドソフトウェアのための簡潔な手続き型言語としてデザインされている。

  • 厳密な型定義
  • 関数 / メソッド
  • インターフェース
  • パッケージ
  • 並列処理

の全てが簡潔に使える。

Goは実は複雑だが、簡潔に感じられるように、簡潔に使えるようにデザインされている。簡潔さは複雑さを隠蔽する芸術である。

Goの簡潔さの特徴として以下のようなものがある。

  • ガベージコレクション
  • ゴルーチン
  • 定数
  • インターフェース
  • パッケージ

それぞれ、実際は複雑だが、簡潔に使えるのが特徴である。

ガベージコレクション

これが最もうまく複雑さを見せずに簡潔に見せかけているものである。Goのコードを簡潔に保てる理由は、ガベージコレクションが存在するからである。コードを書く方は全く意識しなくて良い。

ゴルーチン

go function(args)

ゴルーチンは、g o という3文字で構成される。とても簡潔である。ガベージコレクションと同じで、スタックのサイズやIDなど、プログラマーは全く気にしなくて良い。他の言語であったら提供されているであろうこれらの事をGoでは全く考えなくていいという所にGoの簡潔さが良く表れている。

定数

Goは厳密な静的型付け言語だが、定数には型を持たせないことが可能であり、実際の数字のように扱うことができる。

var nanosecond = time.Second/1e9

これに関しては、この記事にとても丁寧に書いてある。
Goの定数の話

インターフェース

インターフェースは、Goの最大かつパワフルな特徴である。ライブラリをデザインするときに効果を発揮する。プログラマーとしてはとても簡潔に使えるが、裏側の複雑さがそれを可能にしている。

例えば、以下の例がそれを強く示している。

type Reader interface {
    Read([]byte) (int, error)
}
var r Reader = os.Stdin // Statically checked.
var x interface{} = os.Stdin // Statically checked.
r = x.(Reader) // Dynamically checked. Must be explicit here - design decision.

パッケージ

パッケージは、プログラムやライブラリを構築するためのデザインである。

package big

import "math/big"

これをデザインするのに長い時間を要した。コンポーネント化・スケーラビリティ・共有・データ隠蔽・分離を可能にした。また、プログラムのデザイン・シンタックス・ネーミング・ビルド・リンク・テストに大きな影響を与えている。

パッケージのパス"math/big"をパッケージ名bigから分離することで、go getのメカニズムを作り出すことができた。実装は複雑なものだが、自然に使うことができる。

まとめ

「簡潔さ」のデザインはとても難しい。「簡潔さ」のビルドはとても複雑である。
しかし、うまくやれば、「簡潔さ」は使いやすい。

Goの成功がそれを物語っている。