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の成功がそれを物語っている。